├── .gitignore ├── Core ├── Gmsh2CodeFem.m ├── gauleg.m ├── GmshLaunch.m ├── RunGmsh.m ├── reorder_node.m ├── reorder_element.m ├── INIT_GEOMETRY.m ├── GET_ELEMENT_LIST.m ├── ADD_TO_LIST.m ├── ADD_DOFS_TO_INTERFACE.m ├── METHOD_BEM.m ├── create_subQ4.m ├── SOLVE_SYSTEM.m ├── PLOT_FEM.m ├── CREATE_INTERFACE_ELEMENTS.m ├── METHOD_FEM.m ├── POST_PROCESS.m ├── BUILD_SYSTEM.m ├── create_subT3.m ├── MANAGE_PATH.m ├── convert_T3_T6.m ├── ADD_BORDER_DOFS.m ├── ADD_DOMAIN.m ├── BUILD_MODEL.m └── BUILD_DOF.m ├── Library ├── Potential_Flow_2D │ └── T6 │ │ ├── notes.pdf │ │ ├── potential.m │ │ ├── element.m │ │ └── velocity.m ├── Potential_Flow_Axi │ └── T6 │ │ ├── notes.pdf │ │ ├── wall.m │ │ ├── potential.m │ │ ├── element.m │ │ ├── velocity.m │ │ └── mach.m ├── Potential_Flow_3D │ └── T4 │ │ ├── wall.m │ │ ├── potential.m │ │ ├── element.m │ │ ├── element_matrixForm.m │ │ ├── velocity.m │ │ └── mach.m ├── Helmholtz_2D │ ├── T3 │ │ ├── element_Empty.m │ │ ├── empty.m │ │ ├── POST_pressure.m │ │ ├── pres.m │ │ ├── dirichlet.m │ │ ├── POST_mesh.m │ │ ├── wall.m │ │ ├── impedance.m │ │ ├── element.m │ │ ├── element_MassAndStiffness.m │ │ └── velocity.m │ └── Q4 │ │ ├── empty.m │ │ ├── POST_pressure.m │ │ ├── POST_mesh.m │ │ ├── wall.m │ │ ├── impedance.m │ │ ├── element.m │ │ └── velocity.m └── Helmholtz_2D_BEM │ └── L2 │ ├── DBEM_Wall_Wall.m │ └── DBEM_Wall_Wall_BurtonMiller.m ├── Examples ├── Helmholtz_2D │ └── Duct │ │ ├── mesh_example.mat │ │ ├── rectangle_T3.geo │ │ ├── boundary.m │ │ ├── domain.m │ │ └── main.m ├── Potential_Flow_2D │ └── Contraction │ │ ├── mesh_example.mat │ │ ├── domain.m │ │ ├── boundary.m │ │ ├── get_flow.m │ │ ├── geometry.m │ │ └── main.m ├── Potential_Flow_Axi │ └── Contraction │ │ ├── mesh_example.mat │ │ ├── domain.m │ │ ├── boundary.m │ │ ├── geometry.m │ │ ├── get_flow.m │ │ └── main.m └── Helmholtz_2D_BEM │ └── DiffractionByPlaneWave │ ├── ElementLength.m │ ├── L2Error.m │ ├── CirclePlanewave_AnalyticalSolution.m │ ├── boundary.m │ ├── domain.m │ ├── PlotResults.m │ ├── main.m │ ├── geobem.m │ └── mainloop.m ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.asv 3 | *.msh -------------------------------------------------------------------------------- /Core/Gmsh2CodeFem.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GwenaelGabard/Code_FEM/HEAD/Core/Gmsh2CodeFem.m -------------------------------------------------------------------------------- /Library/Potential_Flow_2D/T6/notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GwenaelGabard/Code_FEM/HEAD/Library/Potential_Flow_2D/T6/notes.pdf -------------------------------------------------------------------------------- /Library/Potential_Flow_Axi/T6/notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GwenaelGabard/Code_FEM/HEAD/Library/Potential_Flow_Axi/T6/notes.pdf -------------------------------------------------------------------------------- /Examples/Helmholtz_2D/Duct/mesh_example.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GwenaelGabard/Code_FEM/HEAD/Examples/Helmholtz_2D/Duct/mesh_example.mat -------------------------------------------------------------------------------- /Examples/Potential_Flow_2D/Contraction/mesh_example.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GwenaelGabard/Code_FEM/HEAD/Examples/Potential_Flow_2D/Contraction/mesh_example.mat -------------------------------------------------------------------------------- /Examples/Potential_Flow_Axi/Contraction/mesh_example.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GwenaelGabard/Code_FEM/HEAD/Examples/Potential_Flow_Axi/Contraction/mesh_example.mat -------------------------------------------------------------------------------- /Library/Potential_Flow_3D/T4/wall.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = wall(~) 2 | 3 | if nargin==0 4 | Ke = [4 3 1 1 1 0]; 5 | return 6 | end 7 | 8 | Ke = zeros(4); 9 | Fe = zeros(4, 1); 10 | Re = zeros(4); 11 | Ve = zeros(4, 1); 12 | -------------------------------------------------------------------------------- /Library/Potential_Flow_Axi/T6/wall.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = wall(~) 2 | 3 | if nargin==0 4 | Ke = [4 3 1 1 1 0]; 5 | return 6 | end 7 | 8 | Ke = zeros(6); 9 | Fe = zeros(6, 1); 10 | Re = zeros(6); 11 | Ve = zeros(6, 1); 12 | -------------------------------------------------------------------------------- /Library/Potential_Flow_3D/T4/potential.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = potential(k) 2 | 3 | if nargin==0 4 | Ke = [3 3 1 1 1 0]; 5 | return 6 | end 7 | 8 | global U 9 | global DOF_ELEMENT BOUNDARY_DATA 10 | 11 | Ke = zeros(4); 12 | Fe = zeros(4,1); 13 | Re = eye(4); 14 | Ve = zeros(4,1); 15 | 16 | Ve(1:3) = BOUNDARY_DATA(1:3,k) - U(DOF_ELEMENT(1:3,k)); 17 | Re(4,4) = 0; -------------------------------------------------------------------------------- /Library/Potential_Flow_2D/T6/potential.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = potential(k) 2 | 3 | if nargin==0 4 | Ke = [3 3 1 1 1 0]; 5 | return 6 | end 7 | 8 | global U 9 | global DOF_ELEMENT BOUNDARY_DATA 10 | 11 | Ke = zeros(6); 12 | Fe = zeros(6, 1); 13 | Re = eye(6); 14 | Ve = zeros(6, 1); 15 | 16 | Ve(1:3) = BOUNDARY_DATA(1:3,k) - U(DOF_ELEMENT(1:3,k)); 17 | Re(4:6,4:6) = 0; 18 | -------------------------------------------------------------------------------- /Library/Potential_Flow_Axi/T6/potential.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = potential(k) 2 | 3 | if nargin==0 4 | Ke = [3 3 1 1 1 0]; 5 | return 6 | end 7 | 8 | global U 9 | global DOF_ELEMENT BOUNDARY_DATA 10 | 11 | Ke = zeros(6); 12 | Fe = zeros(6, 1); 13 | Re = eye(6); 14 | Ve = zeros(6, 1); 15 | 16 | Ve(1:3) = BOUNDARY_DATA(1:3,k) - U(DOF_ELEMENT(1:3,k)); 17 | Re(4:6,4:6) = 0; 18 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D_BEM/DiffractionByPlaneWave/ElementLength.m: -------------------------------------------------------------------------------- 1 | function [Le] = ElementLength(Order) 2 | 3 | global NODE ELEMENT N_ELEMENT 4 | 5 | N = Order*3; 6 | [point,weight] = gauleg(-1,1,N); 7 | Le = zeros(1,N_ELEMENT); 8 | for k = 1:N_ELEMENT 9 | x_node = NODE(1,ELEMENT(:,k)).'; 10 | y_node = NODE(2,ELEMENT(:,k)).'; 11 | for m = 1:N 12 | u = point(m); 13 | [~,dNu] = shape_function(u,Order); 14 | Jm = [dNu*x_node dNu*y_node]; 15 | Le(k) = Le(k) + weight(m)*norm(Jm); 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /Examples/Potential_Flow_2D/Contraction/domain.m: -------------------------------------------------------------------------------- 1 | function [out] = domain(~,x) 2 | % domain() returns the number of domains 3 | % domain(i) returns a description of the ith domain 4 | % domain(i,x) returns of vector of properties in the ith domain for the 5 | % node with coordinates x 6 | 7 | if nargin == 0 8 | out = 1; 9 | return 10 | end 11 | 12 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 | if nargin == 1 14 | out = {{'Library/Potential_Flow_2D' 'METHOD_FEM' 'T6' 'element'}}; 15 | return 16 | end 17 | 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | if nargin == 2 20 | out = zeros(1,size(x,2)); 21 | return 22 | end 23 | -------------------------------------------------------------------------------- /Examples/Potential_Flow_Axi/Contraction/domain.m: -------------------------------------------------------------------------------- 1 | function [out] = domain(~,x) 2 | % domain() returns the number of domains 3 | % domain(i) returns a description of the ith domain 4 | % domain(i,x) returns of vector of properties in the ith domain for the 5 | % node with coordinates x 6 | 7 | if nargin == 0 8 | out = 1; 9 | return 10 | end 11 | 12 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 | if nargin == 1 14 | out = {{'Library/Potential_Flow_Axi' 'METHOD_FEM' 'T6' 'element'}}; 15 | return 16 | end 17 | 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | if nargin == 2 20 | out = zeros(1,size(x,2)); 21 | return 22 | end 23 | -------------------------------------------------------------------------------- /Core/gauleg.m: -------------------------------------------------------------------------------- 1 | function [x,w] = gauleg(x1,x2,n) 2 | % Gauss legendre quadrature of order n between x1 and x2 3 | m = (n+1)/2; 4 | xm = 0.5*(x2+x1); 5 | xl = 0.5*(x2-x1); 6 | 7 | EPS = 3.0E-14; 8 | 9 | x = zeros(1,n); 10 | w = zeros(1,n); 11 | for i=1:m 12 | z = cos(pi*(i-0.25)/(n+0.5)); 13 | z1 = z +10; 14 | while abs(z-z1)>EPS 15 | p1 = 1; 16 | p2 = 0; 17 | for j =1:n 18 | p3 = p2; 19 | p2 = p1; 20 | p1 = ((2*j-1)*z*p2-(j-1)*p3)/j; 21 | end 22 | pp = n*(z*p1-p2)/(z*z-1); 23 | z1 = z; 24 | z = z1-p1/pp; 25 | end 26 | x(i) = xm-xl*z; 27 | x(n+1-i) = xm+xl*z; 28 | w(i) = 2*xl/((1-z*z)*pp*pp); 29 | w(n+1-i) = w(i); 30 | end 31 | 32 | return 33 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D_BEM/DiffractionByPlaneWave/L2Error.m: -------------------------------------------------------------------------------- 1 | function Er = L2Error(U,Ua) 2 | 3 | % Computing the L2 error 4 | 5 | global ELEMENT NODE N_ELEMENT DOF_ELEMENT 6 | global N_GAUSS_POINT Order 7 | 8 | A = 0; 9 | B = 0; 10 | 11 | for m = 1:N_ELEMENT 12 | x_nodem = NODE(1,ELEMENT(:,m))'; 13 | y_nodem = NODE(2,ELEMENT(:,m))'; 14 | [GAUSS_POINTM,GAUSS_WEIGHTM] = gauleg(-1,1,N_GAUSS_POINT); 15 | 16 | for mm = 1:N_GAUSS_POINT 17 | u = GAUSS_POINTM(mm); 18 | [Nu,dNu] = shape_function(u,Order); 19 | J = norm([dNu*x_nodem dNu*y_nodem]); 20 | Phi = Nu*U(DOF_ELEMENT(:,m)); 21 | Phia = Nu*Ua(DOF_ELEMENT(:,m)); 22 | A = A + GAUSS_WEIGHTM(mm)*J*( abs(Phi-Phia)^2 ); 23 | B = B + GAUSS_WEIGHTM(mm)*J*(abs(Phia)^2 ); 24 | 25 | end 26 | end 27 | 28 | Er = 100*sqrt(A/B); -------------------------------------------------------------------------------- /Examples/Helmholtz_2D_BEM/DiffractionByPlaneWave/CirclePlanewave_AnalyticalSolution.m: -------------------------------------------------------------------------------- 1 | function [U] = CirclePlanewave_AnalyticalSolution(node,a) 2 | 3 | global omega 4 | 5 | % Analytical solution of the diffraction of a plane wave by a circle (zero 6 | % incidence) 7 | 8 | k = omega/340; 9 | [T,R] = cart2pol(node(1,:),node(2,:)); 10 | Phiinc = exp(1i*k*node(1,:)); 11 | r = a; 12 | Phida = - ((besselj(1,k*a))/besselh(1,1,k*a))*besselh(0,1,k*r)+0*length(T); 13 | 14 | for temp = 1:10000 15 | dJa = 0.5*k*(besselj(temp-1,k*a)-besselj(temp+1,k*a)); 16 | dYa = 0.5*k*(bessely(temp-1,k*a)-bessely(temp+1,k*a)); 17 | dHa = dJa+1i*dYa; 18 | temp2 = - 2*1i^temp*cos(temp*T)*(dJa/dHa)*besselh(temp,1,k*r); 19 | if isnan(temp2)==0 20 | Phida = Phida + temp2; 21 | else 22 | break 23 | end 24 | end 25 | 26 | % Total field 27 | U = (Phida + Phiinc).'; 28 | -------------------------------------------------------------------------------- /Core/GmshLaunch.m: -------------------------------------------------------------------------------- 1 | function GmshLaunch(gmeshFile,ParameterName,ParameterValue,NrOfParameters,NrOfdimensions,outfile) 2 | % launches gmesh meshing 3 | % Gmesh should be recognized as an internal command -> put the executable in the System32 folder in Windows 4 | % 1. Modifies the parameters in the .geo file 5 | % 2. Launches gmesh mesh with NrOfdimensions 6 | % 3. Convert the .msh to the CodeFem format 7 | 8 | % 1. Modify the entries of the .geo file 9 | fid = fopen([gmeshFile '.geo'],'r+'); 10 | frewind(fid); 11 | for iParameter=1:NrOfParameters 12 | fprintf(fid,[ParameterName{iParameter} ' = %10.5f;\n'],ParameterValue(iParameter)); 13 | end 14 | fprintf(fid,'\n\n\n\n ///////////////////'); 15 | % 16 | fclose(fid); 17 | % 2. Launch gmsh 18 | dos(['gmsh ' gmeshFile ['.geo -' num2str(NrOfdimensions) ' -v 0']]); 19 | % 3. Convert the .msh to the CodeFem format 20 | Gmsh2CodeFem([gmeshFile '.msh'],outfile); -------------------------------------------------------------------------------- /Core/RunGmsh.m: -------------------------------------------------------------------------------- 1 | function RunGmsh(GeoFile, Parameters, NrOfdimensions, Output) 2 | 3 | % Open the output file 4 | outfile = fopen([Output '.geo'], 'w+'); 5 | 6 | % Write the definitions of the parameters 7 | names = fieldnames(Parameters); 8 | for n=1:length(names) 9 | if isfloat(Parameters.(names{n})) 10 | fprintf(outfile, [names{n} ' = %.16f;\n'], Parameters.(names{n})); 11 | end 12 | end 13 | fprintf(outfile, '\n'); 14 | 15 | % Open the original file 16 | infile = fopen(GeoFile, 'r+'); 17 | % Copy its content into the output file 18 | while ~feof(infile) 19 | x = fgets(infile); 20 | fprintf(outfile, '%s', x); 21 | end 22 | 23 | fclose(infile); 24 | fclose(outfile); 25 | 26 | % Run gmsh to produce the .msh file 27 | system(['gmsh ' Output ['.geo -' num2str(NrOfdimensions) ' -optimize_ho -v 0 -format msh2' ]]); 28 | 29 | % Parse the .msh file to create the elements 30 | Gmsh2CodeFem([Output '.msh'], Output); 31 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D_BEM/DiffractionByPlaneWave/boundary.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | function [out] = boundary(d,bs,x) 17 | 18 | if nargin == 2 19 | list = {}; 20 | return 21 | end 22 | 23 | if nargin == 3 24 | out = 0; 25 | return 26 | end 27 | 28 | 29 | -------------------------------------------------------------------------------- /Core/reorder_node.m: -------------------------------------------------------------------------------- 1 | function [p,inv_p] = reorder_node(element,nn) 2 | % 3 | % Calculate an optimized numbering of the nodes that minimizes the 4 | % bandwidth of the node graph. 5 | % Usage: 6 | % [p,inv_p] = reorder_element(element,nn) 7 | % element is a matrix where each column corresponds to an element. 8 | % nn is the number of nodes per element. 9 | % p is a permutation vector. 10 | % p_inv is the inverse permutation vector. 11 | 12 | element = element(1:nn,:); 13 | ii = zeros(nn^2,size(element,2)); 14 | jj = zeros(nn^2,size(element,2)); 15 | 16 | for n=1:nn 17 | ii((1:nn)+(n-1)*nn,:) = element; 18 | jj((1:nn)+(n-1)*nn,:) = ones(nn,1)*element(n,:); 19 | end 20 | % Build a spare matrix with 1 on the component a_ij when the nodes i and j 21 | % are connected. 22 | K = sparse(ii(:),jj(:),ones(size(element,2)*nn^2,1)); 23 | % Use the symetric reversed Cuthill-McKee method to reduce the bandwidth 24 | p = symrcm(K); 25 | % Get the inverse permutation 26 | [~,inv_p] = sort(p); 27 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D/Duct/rectangle_T3.geo: -------------------------------------------------------------------------------- 1 | H = 2.00000; 2 | L = 2.00000; 3 | MeshLength = 0.05000; 4 | 5 | 6 | 7 | 8 | ////////////////////////////////////////////////////////////////// 9 | 10 | Mesh.ElementOrder = 1; 11 | 12 | // Physical surface domain 13 | DOMAIN_1 = 1000; 14 | 15 | BOUNDARY_1001 = 1001; 16 | BOUNDARY_1002 = 1002; 17 | BOUNDARY_1003 = 1003; 18 | BOUNDARY_1004 = 1004; 19 | 20 | 21 | Point(4) = {0, 0, 0, MeshLength}; 22 | Point(1) = {L, 0, 0, MeshLength}; 23 | Point(2) = {L, H, 0, MeshLength}; 24 | Point(3) = {0, H, 0, MeshLength}; 25 | 26 | Line(1) = {1,2}; 27 | Line(2) = {2,3}; 28 | Line(3) = {3,4}; 29 | Line(4) = {4,1}; 30 | 31 | Line Loop(9) = {4,1,2,3}; 32 | Plane Surface(10) = {9}; 33 | 34 | // Define the physical groups to apply the boundary conditions 35 | Physical Line(BOUNDARY_1001) = {4}; 36 | Physical Line(BOUNDARY_1002) = {1}; 37 | Physical Line(BOUNDARY_1003) = {2}; 38 | Physical Line(BOUNDARY_1004) = {3}; 39 | 40 | // Physical domain 41 | Physical Surface(DOMAIN_1) = {10}; 42 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/T3/element_Empty.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [Ke,Fe,Me,Ve] = element_Empty(k) 18 | % Returns Empty matrices 19 | 20 | if nargin==0 21 | Ke = [1 3 1 1 1 0]; 22 | return 23 | end 24 | 25 | % Initialise the output 26 | Ke = zeros(3,3); 27 | Fe = zeros(3,1); 28 | Me = zeros(3,3); 29 | Ve = zeros(3,1); 30 | -------------------------------------------------------------------------------- /Examples/Potential_Flow_Axi/Contraction/boundary.m: -------------------------------------------------------------------------------- 1 | function [out] = boundary(~,bs,~) 2 | % boundary(d, bs) returns the type of boundary condition for the boundary 3 | % bs of domain d 4 | % boundary(d, bs, x) returns the properties associated to the point x on 5 | % the boundary bs of domain d 6 | 7 | % Boundaries 1: cylindrical axis 8 | % Boundary 2: duct termination on the right 9 | % Boundaries 3, 4, 5: upper wall (straight, curved, straight) 10 | % Boundary 6: duct termination on the left 11 | 12 | if nargin == 2 13 | list = {'velocity','velocity','velocity','velocity','velocity','potential'}; 14 | out = list{bs}; 15 | return 16 | end 17 | 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | global Flow 20 | if nargin == 3 21 | switch bs 22 | case 1 23 | out = 0; 24 | case 2 25 | out = Flow.outlet_velocity; 26 | case 3 27 | out = 0; 28 | case 4 29 | out = 0; 30 | case 5 31 | out = 0; 32 | case 6 33 | out = 0; 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /Examples/Potential_Flow_2D/Contraction/boundary.m: -------------------------------------------------------------------------------- 1 | function [out] = boundary(~,bs,~) 2 | % boundary(d, bs) returns the type of boundary condition for the boundary 3 | % bs of domain d 4 | % boundary(d, bs, x) returns the properties associated to the point x on 5 | % the boundary bs of domain d 6 | 7 | % Boundaries 1, 2, 3: lower wall (straight, curved, straight) 8 | % Boundary 4: duct termination on the right 9 | % Boundaries 5, 6, 7: upper wall (straight, curved, straight) 10 | % Boundary 8: duct termination on the left 11 | 12 | if nargin == 2 13 | list = {'velocity','velocity','velocity','velocity','velocity','velocity','velocity','potential'}; 14 | out = list{bs}; 15 | return 16 | end 17 | 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | global Flow 20 | if nargin == 3 21 | switch bs 22 | case 1 23 | out = 0; 24 | case 2 25 | out = 0; 26 | case 3 27 | out = 0; 28 | case 4 29 | out = Flow.outlet_velocity; 30 | case 5 31 | out = 0; 32 | case 6 33 | out = 0; 34 | case 7 35 | out = 0; 36 | case 8 37 | out = 0; 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/Q4/empty.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | function [Ke,Fe,Re,Ve] = empty(k) 17 | 18 | 19 | if nargin==0 20 | % Return the properties of the element 21 | % Ke should contain: 22 | % the priority of the element 23 | % the number of nodes 24 | % the number of DOFs for node 1 25 | % the number of DOFs for node 2 26 | % ... 27 | % the number of internal DOFs of the element 28 | Ke = [1 2 1 1 0]; 29 | return 30 | end 31 | 32 | Ke = zeros(2,2); 33 | Fe = zeros(2,1); 34 | Re = zeros(2,2); 35 | Ve = zeros(2,1); 36 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/T3/empty.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | function [Ke,Fe,Re,Ve] = empty(k) 17 | 18 | 19 | if nargin==0 20 | % Return the properties of the element 21 | % Ke should contain: 22 | % the priority of the element 23 | % the number of nodes 24 | % the number of DOFs for node 1 25 | % the number of DOFs for node 2 26 | % ... 27 | % the number of internal DOFs of the element 28 | Ke = [1 2 1 1 0]; 29 | return 30 | end 31 | 32 | Ke = zeros(2,2); 33 | Fe = zeros(2,1); 34 | Re = zeros(2,2); 35 | Ve = zeros(2,1); 36 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D_BEM/DiffractionByPlaneWave/domain.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | function [out] = domain(d,x) 17 | 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | if nargin == 0 20 | out = 1; 21 | return 22 | end 23 | 24 | if nargin == 1 25 | %out = {{'Library/Helmholtz_2D_BEM' 'METHOD_BEM' 'L2' 'DBEM_Wall_Wall'}}; 26 | out = {{'Library/Helmholtz_2D_BEM' 'METHOD_BEM' 'L2' 'DBEM_Wall_Wall_BurtonMiller'}}; 27 | return 28 | end 29 | 30 | RHO0 = 1.2; 31 | C0 = 340; 32 | 33 | if nargin == 2 34 | out = RHO0*ones(1,size(x,2)); 35 | out = [out ; C0*ones(1,size(x,2))]; 36 | return 37 | end 38 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D_BEM/DiffractionByPlaneWave/PlotResults.m: -------------------------------------------------------------------------------- 1 | 2 | % Open problems 3 | if strcmp(typegeo,'linev')%|strcmp(typegeo,'circlearc') 4 | figure; subplot(1,2,1); 5 | plot(NODE(2,:),abs(U),'r'); 6 | axis square; axis tight; 7 | elseif strcmp(typegeo,'spiral') 8 | [T,R] = cart2pol(NODE(1,:),NODE(2,:)); 9 | figure; 10 | subplot(1,2,1); 11 | plot(R*2*pi,abs(U),'k');hold on; 12 | axis tight; axis square; 13 | % Classical 14 | else 15 | [T,R] = cart2pol(NODE(1,:),NODE(2,:)); 16 | T(find(T<0))=2*pi+T(find(T<0)); 17 | T=T*180/pi; 18 | mini = find(T==min(T)); 19 | T = [T( mini:end ) T(1:mini-1) ]; 20 | figure; 21 | subplot(1,2,1); 22 | U = [U( mini:end ); U(1:mini-1)]; 23 | plot(T,real(U),'k');hold on;set(gca,'Xlim',[0 360]); 24 | Uanal = [Uanal( mini:end ); Uanal(1:mini-1)]; 25 | axis square; axis tight; 26 | plot(T,real(Uanal),'k.'); 27 | xlabel('Angle: degree'); 28 | title('Analytic numeric comparison'); 29 | axis square; axis tight; 30 | end 31 | 32 | % Plot the Mesh 33 | subplot(1,2,2);list = []; 34 | for temp=1:N_NODE 35 | if isempty(find([ELEMENT(1,:) ELEMENT(end,:)]==temp))==0 36 | list = [list temp]; 37 | end 38 | end 39 | plot(NODE(1,:),NODE(2,:),'k.',NODE(1,list),NODE(2,list),'r*'); 40 | title('Geometry');axis equal; axis tight; 41 | 42 | -------------------------------------------------------------------------------- /Core/reorder_element.m: -------------------------------------------------------------------------------- 1 | function [p,inv_p] = reorder_element(element,nn) 2 | % 3 | % Calculate an optimized numbering of the elements that minimizes the 4 | % bandwidth of the element graph. 5 | % Usage: 6 | % [p,inv_p] = reorder_element(element,nn) 7 | % element is a matrix where each column corresponds to an element. 8 | % nn is the number of nodes per element. 9 | % p is a permutation vector. 10 | % p_inv is the inverse permutation vector. 11 | 12 | % Compute the connectivity between elements 13 | segment = [ ]; 14 | seg_elem = 1:size(element,2); 15 | for n=1:nn-1 16 | segment = [ segment element(n:n+1,:) ]; %#ok 17 | seg_elem = [ seg_elem (1:size(element,2)) ]; %#ok 18 | end 19 | segment = [ segment [ element(nn,:) ; element(1,:) ] ]; 20 | temp = sparse(segment(1,:),segment(2,:),seg_elem); 21 | [ii,jj,ss] = find(temp .* ((temp~=0).*(temp.'~=0))); 22 | edge = [ii' ; jj' ; ss']; 23 | [~,~,ss] = find(temp.' .* ((temp~=0).*(temp.'~=0))); 24 | edge = [edge ; ss']; 25 | edge = edge(:,edge(3,:)>edge(4,:)); 26 | 27 | % Build a spare matrix with 1 on the component a_ij when the elements i and 28 | % j are neighbours. 29 | K = sparse(edge(3,:),edge(4,:),ones(1,size(edge,2)),size(element,2),size(element,2)); 30 | % Use the symetric reversed Cuthill-McKee method to reduce the bandwidth 31 | p = symrcm(K); 32 | % Get the inverse permutation 33 | [~,inv_p] = sort(p); 34 | -------------------------------------------------------------------------------- /Core/INIT_GEOMETRY.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | % Declare and initialise the variables needed to describe the geometry of 18 | % the problem 19 | 20 | clear N_DIM N_NODE NODE 21 | clear N_ELEMENT N_NODE_ELEMENT ELEMENT 22 | clear N_DOMAIN ELEMENT_DOMAIN NODE_DOMAIN 23 | 24 | global N_DIM N_NODE NODE %#ok 25 | global N_ELEMENT N_NODE_ELEMENT ELEMENT 26 | global N_DOMAIN ELEMENT_DOMAIN NODE_DOMAIN 27 | global ELEMENT_ID NODE_ID 28 | 29 | N_NODE = 0; 30 | N_ELEMENT = 0; 31 | N_DOMAIN = 0; 32 | NODE = []; 33 | N_NODE_ELEMENT = []; 34 | ELEMENT = []; 35 | ELEMENT_DOMAIN = []; 36 | NODE_DOMAIN = []; 37 | ELEMENT_ID = []; 38 | NODE_ID = []; 39 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D/Duct/boundary.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [out] = boundary(d,bs,x) 18 | 19 | % boundary(d, bs) returns the type of boundary condition for the boundary 20 | % bs of domain d 21 | if nargin == 2 22 | list = {'wall', 'impedance', 'wall', 'wall'}; 23 | out = list{bs}; 24 | return 25 | end 26 | 27 | % boundary(d, bs, x) returns the properties associated to the point x on 28 | % the boundary bs of domain d 29 | if nargin == 3 30 | switch bs 31 | case 1 32 | out = 0; 33 | case 2 34 | out = 1; 35 | case 3 36 | out = 0; 37 | case 4 38 | out = 1; 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /Core/GET_ELEMENT_LIST.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function a = GET_ELEMENT_LIST(d,t,g) 18 | % Return the list of the elements that are in domain d, and of type t 19 | % (0: domain, 1: boundary), and in group g. 20 | % If no group g is provided then all the elements in domain d and of type t 21 | % are returned. 22 | 23 | global ELEMENT_DOMAIN 24 | 25 | if nargin==3 26 | a = find((ELEMENT_DOMAIN(1,:)==d)&(ELEMENT_DOMAIN(2,:)==t)&(ELEMENT_DOMAIN(3,:)==g(1))); 27 | if length(g)>1 28 | for n=2:length(g) 29 | a = [ a find((ELEMENT_DOMAIN(1,:)==d)&(ELEMENT_DOMAIN(2,:)==t)&(ELEMENT_DOMAIN(3,:)==g(n))) ]; %#ok 30 | end 31 | end 32 | elseif nargin==2 33 | a = find((ELEMENT_DOMAIN(1,:)==d)&(ELEMENT_DOMAIN(2,:)==t)); 34 | end 35 | -------------------------------------------------------------------------------- /Examples/Potential_Flow_Axi/Contraction/geometry.m: -------------------------------------------------------------------------------- 1 | function [x,y] = geometry(bs,s,x) 2 | % CONVENTION AXI : R=X 3 | % Z=Y 4 | 5 | nbs = 6; 6 | H = 1; 7 | L = 1; 8 | D = 2; 9 | C = 0.3; 10 | 11 | % Return the number of boundary segments 12 | if nargin == 0, 13 | x = nbs; 14 | return 15 | end 16 | 17 | d = [0 0 0 0 0 0 0 0 % start parameter value 18 | 1 1 1 1 1 1 1 1 % end parameter value 19 | 1 1 1 1 1 1 1 1 % left hand region 20 | 0 0 0 0 0 0 0 0 % right hand region 21 | ]; 22 | bs1 = bs(:)'; 23 | if find(bs1<1 | bs1>nbs), 24 | error('Non existent boundary segment number') 25 | end 26 | 27 | if nargin == 1, 28 | x = d(:,bs1); 29 | return 30 | end 31 | 32 | if nargin == 2 33 | x = zeros(size(s)); 34 | y = zeros(size(s)); 35 | [m,n] = size(bs); 36 | if m==1 && n==1, 37 | bs = bs*ones(size(s)); % expand bs 38 | elseif m~=size(s,1) || n~=size(s,2), 39 | error('bs must be scalar or of same size as s'); 40 | end 41 | 42 | if ~isempty(s) 43 | ii = find(bs==1); 44 | x(ii) = 0 + (L+D+L)*s(ii); 45 | y(ii) = 0; 46 | ii = find(bs==2); 47 | x(ii) = L+D+L; 48 | y(ii) = H*s(ii); 49 | ii = find(bs==3); 50 | x(ii) = L+D+L - L*s(ii); 51 | y(ii) = H; 52 | ii = find(bs==4); 53 | x(ii) = L+D - D*s(ii); 54 | y(ii) = H - C*(1-cos(2*pi*s(ii)))/2; 55 | ii = find(bs==5); 56 | x(ii) = L - L*s(ii); 57 | y(ii) = H; 58 | ii = find(bs==6); 59 | x(ii) = 0; 60 | y(ii) = H*(1-s(ii)); 61 | end 62 | return 63 | end 64 | -------------------------------------------------------------------------------- /Core/ADD_TO_LIST.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [number,list]=ADD_TO_LIST(list,token) 18 | % list : a list of strings 19 | % token : a string 20 | % If token is already in the list then list remain unchanged 21 | % and number is the index where token is in the list. 22 | % If token isn't in the list, we add it to the list and return the 23 | % corresponding index in the list in number. 24 | % Upper and lower cases are different. 25 | % Example : 26 | % list = {'alpha','beta','Alpha'}; 27 | % [number,list] = ADD_TO_LIST(list,'beta') 28 | % [number,list] = ADD_TO_LIST(list,'Beta') 29 | 30 | temp = find(strcmp(list,token)); 31 | if isempty(temp) 32 | % token is not yet in the list 33 | list = [list cellstr(token)]; 34 | number = length(list); 35 | else 36 | % token is already in the list 37 | number = temp; 38 | end 39 | -------------------------------------------------------------------------------- /Core/ADD_DOFS_TO_INTERFACE.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function ADD_DOFS_TO_INTERFACE(d, t, g) 18 | % Modify interface elements so that they include the degrees of freedom of 19 | % the two elements on either side. 20 | % d: domain number 21 | % t: type of elements 22 | % g: list of group numbers of the interface elements to modify 23 | 24 | global ELEMENT N_NODE_ELEMENT 25 | global DOF_ELEMENT N_DOF_ELEMENT 26 | 27 | list = GET_ELEMENT_LIST(d,t,g); 28 | 29 | for e=list 30 | % Number of the elements on either side 31 | e1 = ELEMENT(N_NODE_ELEMENT(e)+1,e); 32 | e2 = ELEMENT(N_NODE_ELEMENT(e)+2,e); 33 | % Number of degrees of freedom on either side 34 | n1 = N_DOF_ELEMENT(e1); 35 | n2 = N_DOF_ELEMENT(e2); 36 | % Update the interface element 37 | N_DOF_ELEMENT(e) = n1 + n2; 38 | DOF_ELEMENT(1:N_DOF_ELEMENT(e),e) = [DOF_ELEMENT(1:n1,e1);DOF_ELEMENT(1:n2,e2)]; 39 | end 40 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D/Duct/domain.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function out = domain(d,x) 18 | 19 | global ELEMENT_DOMAIN NODE ELEMENT 20 | 21 | % domain() returns the number of domains 22 | if nargin == 0 23 | out = 2; 24 | return 25 | end 26 | 27 | % domain(i) returns a description of the ith domain 28 | if nargin == 1 29 | % Domain 1 30 | out = {{'Library/Helmholtz_2D' 'METHOD_FEM' 'T3' 'element'}}; 31 | return 32 | end 33 | 34 | % domain(i,x) returns of vector of properties in the ith domain for the 35 | % node with coordinates x 36 | RHO0 = 1; % Fluid mean density 37 | C0 = 1; % Mean sound speed 38 | if nargin == 2 39 | out = zeros(5,size(x,2)); 40 | out(1,:) = RHO0; % rho0 41 | out(2,:) = C0; % c0 42 | out(3,:) = 0; % U0x 43 | out(4,:) = 0; % U0y 44 | out(5,:) = 0; % Source term 45 | return 46 | end 47 | -------------------------------------------------------------------------------- /Examples/Potential_Flow_2D/Contraction/get_flow.m: -------------------------------------------------------------------------------- 1 | % Calculate the flow properties at the nodes of the T6 mesh 2 | 3 | % Coordinates of the points 4 | UInt = [0 0.5 1 0.5 0 0]; 5 | VInt = [0 0 0 0.5 1 0.5]; 6 | 7 | % Shape functions and their derivatives 8 | WInt = 1 - UInt - VInt; 9 | N = [ (2*WInt-1).*WInt ; 4*UInt.*WInt ; (2*UInt-1).*UInt ; 4*UInt.*VInt ; (2*VInt-1).*VInt ; 4*VInt.*WInt ]; 10 | dNdu = [ 1-4*WInt ; 4*(WInt-UInt) ; 4*UInt-1 ; 4*VInt ; 0*UInt ; -4*VInt ]; 11 | dNdv = [ 1-4*WInt ; -4*UInt ; 0*UInt ; 4*UInt ; 4*VInt-1 ; 4*(WInt-VInt) ]; 12 | 13 | % In each element we calculate the gradient of the velocity potential. 14 | % We end up with several values of the velocity since the nodes are shared 15 | % by several elements. The average of these values is calculated. 16 | ElemList = find(ELEMENT_DOMAIN(2,:)==0); 17 | Vx = zeros(1, size(NODE, 2)); 18 | Vy = Vx; 19 | NV = Vx; 20 | for k=ElemList 21 | nn = ELEMENT(1:6,k); 22 | xn = NODE(1:2, nn).'; 23 | Ue = full(U(DOF_ELEMENT(1:N_DOF_ELEMENT(k),k)).').'; 24 | for n=1:length(nn) 25 | GRAD = [dNdu(:,n) dNdv(:,n)]'; 26 | J = GRAD*xn; 27 | GRAD = J\GRAD; 28 | dphi = GRAD*Ue; 29 | Vx(nn(n)) = Vx(nn(n)) + dphi(1); 30 | Vy(nn(n)) = Vy(nn(n)) + dphi(2); 31 | end 32 | NV(nn) = NV(nn) +1; 33 | end 34 | % Average the values 35 | Vx = Vx./NV; 36 | Vy = Vy./NV; 37 | 38 | % Velocity normal 39 | V2 = Vx.^2 + Vy.^2; 40 | V = sqrt(V2); 41 | 42 | % Density 43 | rho = Flow.rho_inf*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-V2)/Flow.c_inf^2 ).^(1/(Flow.gamma-1)); 44 | 45 | % Sound speed 46 | c2 = Flow.c_inf^2*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-V2)/Flow.c_inf^2 ); 47 | c = sqrt(c2); 48 | -------------------------------------------------------------------------------- /Examples/Potential_Flow_Axi/Contraction/get_flow.m: -------------------------------------------------------------------------------- 1 | % Calculate the flow properties at the nodes of the T6 mesh 2 | 3 | % Coordinates of the points 4 | UInt = [0 0.5 1 0.5 0 0]; 5 | VInt = [0 0 0 0.5 1 0.5]; 6 | 7 | % Shape functions and their derivatives 8 | WInt = 1 - UInt - VInt; 9 | N = [ (2*WInt-1).*WInt ; 4*UInt.*WInt ; (2*UInt-1).*UInt ; 4*UInt.*VInt ; (2*VInt-1).*VInt ; 4*VInt.*WInt ]; 10 | dNdu = [ 1-4*WInt ; 4*(WInt-UInt) ; 4*UInt-1 ; 4*VInt ; 0*UInt ; -4*VInt ]; 11 | dNdv = [ 1-4*WInt ; -4*UInt ; 0*UInt ; 4*UInt ; 4*VInt-1 ; 4*(WInt-VInt) ]; 12 | 13 | % In each element we calculate the gradient of the velocity potential. 14 | % We end up with several values of the velocity since the nodes are shared 15 | % by several elements. The average of these values is calculated. 16 | ElemList = find(ELEMENT_DOMAIN(2,:)==0); 17 | Vx = zeros(1, size(NODE, 2)); 18 | Vy = Vx; 19 | NV = Vx; 20 | for k=ElemList 21 | nn = ELEMENT(1:6,k); 22 | xn = NODE(1:2, nn).'; 23 | Ue = full(U(DOF_ELEMENT(1:N_DOF_ELEMENT(k),k)).').'; 24 | for n=1:length(nn) 25 | GRAD = [dNdu(:,n) dNdv(:,n)]'; 26 | J = GRAD*xn; 27 | GRAD = J\GRAD; 28 | dphi = GRAD*Ue; 29 | Vx(nn(n)) = Vx(nn(n)) + dphi(1); 30 | Vy(nn(n)) = Vy(nn(n)) + dphi(2); 31 | end 32 | NV(nn) = NV(nn) +1; 33 | end 34 | % Average the values 35 | Vx = Vx./NV; 36 | Vy = Vy./NV; 37 | 38 | % Velocity normal 39 | V2 = Vx.^2 + Vy.^2; 40 | V = sqrt(V2); 41 | 42 | % Density 43 | rho = Flow.rho_inf*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-V2)/Flow.c_inf^2 ).^(1/(Flow.gamma-1)); 44 | 45 | % Sound speed 46 | c2 = Flow.c_inf^2*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-V2)/Flow.c_inf^2 ); 47 | c = sqrt(c2); 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Code FEM 2 | 3 | This Matlab program provides a platform to facilitate the implementation of 4 | Finite Element and Boundary Element formulations. It is intended as a research 5 | tool. 6 | 7 | 8 | ## Structure 9 | 10 | Three levels can be considered. 11 | 12 | 1. Using an existing finite element formulation to solve a given problem. 13 | 14 | 2. Implementation and validating a new finite element formulation. This is the 15 | main purpose of this code. It is designed to make it (relatively) easy to 16 | go from a variational formulation on paper to a working implementation that can 17 | be validated and assessed. The different finite element formulations, or boundary 18 | element formulations, available are located in the Library directory. 19 | 20 | 3. The low level and generic tasks required by all finite element models, such 21 | as allocating degrees of freedom, the assembly of element matrices in a global 22 | system. All these aspects are provided by functions and scripts in the Core 23 | directory. 24 | 25 | 26 | ## Documentation 27 | 28 | Further details will be made available in the Documentation directory. 29 | 30 | 31 | ## Examples 32 | 33 | See the Examples directory. 34 | 35 | 36 | ## Some background 37 | 38 | The first version of this code was originally developed at the Acoustics Group 39 | at the University of Technology of Compiegne, France, back in 2000. Various 40 | revisions were further develop, and the code was used for several research 41 | projects. It has since been used in other research groups, leading to several 42 | different version being developed independently. This repository is an attempt 43 | to bring some of these features together. 44 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/Q4/POST_pressure.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function out = POST_pressure(k) 18 | % k is the number of the domain to plot 19 | 20 | global U DOF_ELEMENT NODE ELEMENT_DOMAIN ELEMENT 21 | 22 | % Return the name of the button shown in the GUI 23 | if nargin==0 24 | out = 'Pressure'; 25 | return 26 | end 27 | 28 | % List of the element in the domain 29 | elem_list = find((ELEMENT_DOMAIN(1,:)==k)&(ELEMENT_DOMAIN(2,:)==0)); 30 | 31 | % Extract the field to plot 32 | DATA = full(U(DOF_ELEMENT(1:3,elem_list))); 33 | DATA = real(DATA); 34 | 35 | % Coordinates of the nodes 36 | X = NODE(1,:); 37 | Y = NODE(2,:); 38 | X = full(X(ELEMENT(1:4,elem_list))); 39 | Y = full(Y(ELEMENT(1:4,elem_list))); 40 | 41 | % Draw the elements 42 | opengl('NeverSelect'); 43 | figure 44 | patch(X,Y,DATA,'Edgecolor','none','Erasemode','normal'); 45 | MIN = min(min(DATA)); 46 | MAX = max(max(DATA)); 47 | caxis([MIN MAX]); 48 | colorbar; 49 | axis equal; axis tight; box on; 50 | xlabel('X'); 51 | ylabel('Y'); 52 | title('Pressure'); 53 | -------------------------------------------------------------------------------- /Core/METHOD_BEM.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % BEM Method 3 | fprintf('METHOD_BEM : Domain %i (%i elements)\n',ELEMENT_DOMAIN(1,list(1)),length(list)); 4 | 5 | %-------------------------- 6 | % DOUBLE INTEGRATION 7 | %------------------------- 8 | % Loop over the elements 9 | for m=1:length(list) 10 | % Loop over the elements 11 | for n=1:length(list) 12 | % call the elementary routine 13 | [Ke,Fe,Re,Ve] = feval(char(ELEMENT_NAME(ELEMENT_LIST(list(m)))),list(m),list(n)); 14 | % List of dofs of element m 15 | dof_listm = DOF_ELEMENT(1:N_DOF_ELEMENT(list(m)),list(m)); 16 | % List of dofs of element n 17 | dof_listn = DOF_ELEMENT(1:N_DOF_ELEMENT(list(n)),list(n)); 18 | % Assembly 19 | K(dof_listm,dof_listn) = K(dof_listm,dof_listn) + Ke; 20 | F(dof_listm) = F(dof_listm)+Fe; 21 | % Sum up the linear relations 22 | Le = find(max(abs(Re),[],2)); 23 | R(dof_listm,dof_listn) = R(dof_listm,dof_listn) + Re; 24 | V(dof_listm) = V(dof_listm) + Ve; 25 | end 26 | end 27 | 28 | %-------------------------- 29 | % SIMPLE INTEGRATION 30 | %------------------------- 31 | for m=1:length(list) 32 | % call the elementary routine 33 | [Ke,Fe,Re,Ve] = feval(char(ELEMENT_NAME(ELEMENT_LIST(list(m)))),list(m)); 34 | % List of dofs of element m 35 | dof_list = DOF_ELEMENT(1:N_DOF_ELEMENT(list(m)),list(m)); 36 | % Assembly 37 | K(dof_list,dof_list) = K(dof_list,dof_list) + Ke; 38 | F(dof_list) = F(dof_list)+Fe; 39 | % Sum up the linear relations 40 | R(dof_list,dof_list) = R(dof_list,dof_list) + Re; 41 | V(dof_list) = V(dof_list) + Ve; 42 | end 43 | 44 | % clear the temp variables 45 | clear Le Fe Ke Re Ve 46 | -------------------------------------------------------------------------------- /Examples/Potential_Flow_2D/Contraction/geometry.m: -------------------------------------------------------------------------------- 1 | function [x,y] = geometry(bs,s,x) 2 | % CONVENTION AXI : R=X 3 | % Z=Y 4 | 5 | nbs = 8; 6 | H = 1; 7 | L = 0.5; 8 | D = 2; 9 | C = 0.2; 10 | 11 | % Return the number of boundary segments 12 | if nargin == 0, 13 | x = nbs; 14 | return 15 | end 16 | 17 | d = [0 0 0 0 0 0 0 0 % start parameter value 18 | 1 1 1 1 1 1 1 1 % end parameter value 19 | 1 1 1 1 1 1 1 1 % left hand region 20 | 0 0 0 0 0 0 0 0 % right hand region 21 | ]; 22 | bs1 = bs(:)'; 23 | if find(bs1<1 | bs1>nbs), 24 | error('Non existent boundary segment number') 25 | end 26 | 27 | if nargin == 1, 28 | x = d(:,bs1); 29 | return 30 | end 31 | 32 | if nargin == 2 33 | x = zeros(size(s)); 34 | y = zeros(size(s)); 35 | [m,n] = size(bs); 36 | if m==1 && n==1, 37 | bs = bs*ones(size(s)); % expand bs 38 | elseif m~=size(s,1) || n~=size(s,2), 39 | error('bs must be scalar or of same size as s'); 40 | end 41 | 42 | if ~isempty(s) 43 | ii = find(bs==1); 44 | x(ii) = 0 + L*s(ii); 45 | y(ii) = 0; 46 | ii = find(bs==2); 47 | x(ii) = L + D*s(ii); 48 | y(ii) = (1-cos(2*pi*s(ii)))/2*C; 49 | ii = find(bs==3); 50 | x(ii) = L+D + L*s(ii); 51 | y(ii) = 0; 52 | ii = find(bs==4); 53 | x(ii) = L+D+L; 54 | y(ii) = H*s(ii); 55 | ii = find(bs==5); 56 | x(ii) = L+D+L - L*s(ii); 57 | y(ii) = H; 58 | ii = find(bs==6); 59 | x(ii) = L+D - D*s(ii); 60 | y(ii) = H - C*(1-cos(2*pi*s(ii)))/2; 61 | ii = find(bs==7); 62 | x(ii) = L - L*s(ii); 63 | y(ii) = H; 64 | ii = find(bs==8); 65 | x(ii) = 0; 66 | y(ii) = H*(1-s(ii)); 67 | end 68 | return 69 | end 70 | -------------------------------------------------------------------------------- /Library/Potential_Flow_3D/T4/element.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = element(k) 2 | % Compressible potential steady flow (3D) 3 | 4 | if nargin==0 5 | Ke = [1 4 1 1 1 1 0]; 6 | return 7 | end 8 | 9 | global Flow 10 | global U 11 | global ELEMENT NODE DOF_ELEMENT 12 | 13 | % Integration points on the tetrahedron with vertices 14 | % (0,0,0), (0,1,0), (1,0,0) and (0,0,1) 15 | N_GAUSS_POINT = 4; 16 | a = (5-sqrt(5))/20; b = (5+3*sqrt(5))/20; 17 | GAUSS_POINT = [ a a a b; a a b a; a b a a ]; 18 | GAUSS_WEIGHT = [1/24 1/24 1/24 1/24]; 19 | 20 | % Node coordinates 21 | x_node = NODE(1,ELEMENT(1:4,k)).'; 22 | y_node = NODE(2,ELEMENT(1:4,k)).'; 23 | z_node = NODE(3,ELEMENT(1:4,k)).'; 24 | 25 | % Current solution 26 | phi = U(DOF_ELEMENT(1:4,k)); 27 | 28 | Ke = zeros(4); 29 | Fe = zeros(4, 1); 30 | Re = zeros(4); 31 | Ve = zeros(4, 1); 32 | 33 | % Assembly 34 | J = [-1 1 0 0 ; -1 0 1 0; -1 0 0 1]*[x_node y_node z_node]; 35 | detJ = det(J); 36 | GRAD = J\[-1 1 0 0 ; -1 0 1 0; -1 0 0 1]; 37 | 38 | for n=1:N_GAUSS_POINT 39 | %u = GAUSS_POINT(1,n); 40 | %v = GAUSS_POINT(2,n); 41 | %w = GAUSS_POINT(3,n); 42 | %************************ 43 | % N = [(1-u-v-w) u v w]; 44 | 45 | dphi = GRAD*phi; 46 | v2 = dphi(1)^2 + dphi(2)^2 + dphi(3)^2; 47 | rho = Flow.rho_inf*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 )^(1/(Flow.gamma-1)); 48 | c2 = Flow.c_inf^2*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 ); 49 | if v2>c2 50 | error('The flow is supersonic: the calculation cannot proceed (c=%f, v=%f).', sqrt(c2), sqrt(v2)); 51 | end 52 | Ke = Ke + GAUSS_WEIGHT(n)*( rho/c2*(dphi'*GRAD)'*(dphi'*GRAD) - rho*(GRAD'*GRAD) )*detJ; 53 | Fe = Fe + GAUSS_WEIGHT(n)*( rho*GRAD'*dphi )*detJ; 54 | end 55 | 56 | 57 | -------------------------------------------------------------------------------- /Core/create_subQ4.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [u,v,c] = create_subQ4(N) 18 | % Create a set of nodes and small triangular elements covering the 19 | % reference quadrilateral element (with 0. 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function out = POST_pressure(k) 18 | % k is the number of the domain to plot 19 | 20 | global U DOF_ELEMENT NODE ELEMENT_DOMAIN ELEMENT 21 | 22 | % Return the name of the button shown in the GUI 23 | if nargin==0 24 | out = 'Pressure'; 25 | return 26 | end 27 | 28 | % List of the element in the domain 29 | elem_list = find((ELEMENT_DOMAIN(1,:)==k)&(ELEMENT_DOMAIN(2,:)==0)); 30 | 31 | % Extract the field to plot 32 | DATA = full(U(DOF_ELEMENT(1:3,elem_list))); 33 | DATA = real(DATA); 34 | 35 | % Coordinates of the nodes 36 | X = NODE(1,:); 37 | Y = NODE(2,:); 38 | X = full(X(ELEMENT(1:3,elem_list))); 39 | Y = full(Y(ELEMENT(1:3,elem_list))); 40 | 41 | % Draw the elements 42 | opengl('NeverSelect'); 43 | figure 44 | patch(X,Y,DATA,'Edgecolor','none','Erasemode','normal'); 45 | MIN = min(min(DATA)); 46 | MAX = max(max(DATA)); 47 | caxis([MIN MAX]); 48 | colorbar; 49 | axis equal; axis tight; box on; 50 | xlabel('X'); 51 | ylabel('Y'); 52 | title('Pressure'); 53 | -------------------------------------------------------------------------------- /Core/SOLVE_SYSTEM.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | % Solve the linear system and implement the linear constraints 18 | 19 | fprintf('SOLVE_SYSTEM: '); 20 | % Find the DOFs that are constrained 21 | L = find(diag(R)); 22 | fprintf('%i constraints', length(L)); 23 | % Find the DOFs that are not constrained 24 | Lbar = find(diag(R)==0); 25 | 26 | % Change of variables to impose the linear constraints 27 | R = R + sparse(Lbar, Lbar, ones(1, length(Lbar)), N_DOF, N_DOF); 28 | R = inv(R); 29 | K = R'*K*R; 30 | F = R'*F; 31 | 32 | % Modify the linear system 33 | K(L,:) = 0; K((L-1)*N_DOF+L) = 1; F(L) = V(L); %(original method - unsymmetric + slow) 34 | % F = F-repmat(K(:,L)*V(L),1,N_RHS); K(L,:) = 0; K(:,L) = 0; 35 | % diagK = diag(K); diagK(L)=1; K = spdiags(diagK,0,K); 36 | % F(L,:) = repmat(V(L),1,N_RHS); 37 | 38 | 39 | % Direct resolution of the linear system 40 | global U 41 | U = K\F; 42 | 43 | % Convert back to the original variables 44 | U = R*U; 45 | fprintf(', %i DOFs\n',N_DOF); 46 | 47 | % Clean up the workspace 48 | clear L Lbar k 49 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D/Duct/main.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | % To find the solver 18 | addpath('../../../../Code_FEM/Core'); 19 | MANAGE_PATH 20 | 21 | % Define some global properties of the problem 22 | global omega 23 | omega = 20; 24 | 25 | % Mesh & domain properties (if external mesher) 26 | MeshLength = 0.05; 27 | Length = 2; 28 | Height = 1; 29 | 30 | % Initialise the geometry description 31 | INIT_GEOMETRY 32 | 33 | % Option 1: Load an existing mesh and add it to the geometry 34 | % load('mesh_example'); 35 | % ADD_DOMAIN(node,edge,element); 36 | % Option 2: use gmsh as an external mesher (http://geuz.org/gmsh/#Download) 37 | GmshLaunch('rectangle_T3',{'H' 'L' 'MeshLength'},[Height Length MeshLength],3,2,'Mesh.mat'); 38 | load('Mesh.mat'); delete('Mesh.mat'); 39 | 40 | % Construct the list of elements and nodes 41 | BUILD_MODEL 42 | 43 | % Create a table of degrees of freedom 44 | BUILD_DOF 45 | 46 | % Assembly of the global linear system of equations 47 | BUILD_SYSTEM 48 | 49 | % Solve the linear system 50 | SOLVE_SYSTEM 51 | 52 | % Start the GUI to plot the solution 53 | POST_PROCESS 54 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/Q4/POST_mesh.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function out=POST_mesh(k) 18 | % k is the number of the domain to plot 19 | 20 | global ELEMENT NODE ELEMENT_DOMAIN 21 | 22 | % Return the name of the button shown in the GUI 23 | if nargin==0 24 | out = 'Mesh'; 25 | return 26 | end 27 | 28 | % List of the elements in the domain 29 | elem_list = find((ELEMENT_DOMAIN(1,:)==k)&(ELEMENT_DOMAIN(2,:)==0)); 30 | % List of the border elements in the domain 31 | border_list = find((ELEMENT_DOMAIN(1,:)==k)&(ELEMENT_DOMAIN(2,:)==1)); 32 | 33 | % Nodes coordinates 34 | X = NODE(1,:); 35 | Y = NODE(2,:); 36 | X = full(X(ELEMENT(1:4,elem_list))); 37 | Y = full(Y(ELEMENT(1:4,elem_list))); 38 | % Number of boundaries 39 | n_border = max(ELEMENT_DOMAIN(3,border_list)); 40 | 41 | figure 42 | flagmap = [0 0 1;0 1 0;1 0 0;1 1 0;0 1 1;1 0 1;0 0 0;1 1 1]; 43 | hold on 44 | patch(X,Y,ones(size(elem_list))*'b','EdgeColor',flagmap(1,:),'FaceColor','none'); 45 | for j=1:n_border 46 | X = NODE(1,:); 47 | Y = NODE(2,:); 48 | border_list = find((ELEMENT_DOMAIN(1,:)==k)&(ELEMENT_DOMAIN(2,:)==1)&(ELEMENT_DOMAIN(3,:)==j)); 49 | X = full(X(ELEMENT(1:2,border_list))); 50 | Y = full(Y(ELEMENT(1:2,border_list))); 51 | patch(X,Y,'w','EdgeColor',flagmap(j+1,:)); 52 | end 53 | hold off 54 | axis equal;axis tight; 55 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/T3/pres.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [Ke,Fe,Re,Ve] = dirichlet(k) 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | % 2D Convected Helmholtz Equation 20 | % Notation: exp(-i \omega t) 21 | % Boundary condition: dirichlet 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % Linear boundary element associated to the T3 element 24 | % 2 nodes 25 | % 2 DOFs: p1, p2 26 | % Data in ELEMENT(:,k) : 27 | % 1,2: node numbers 28 | % 3,4: coordinates along the boundary 29 | % 5: number of this boundary 30 | % 6: number of the neighboring element 31 | % 7: number of the side in the neighboring element 32 | % Data in ELEMENT_DATA(:,k): 33 | % None 34 | % Data in NODE_DATA(:,k): 35 | % None 36 | % Data in BOUNDARY_DATA(:,k): 37 | % 1: solution at node 1 38 | % 2: solution at node 2 39 | 40 | if nargin==0 41 | % Return the properties of the element 42 | % Ke should contain: 43 | % the priority of the element 44 | % the number of nodes 45 | % the number of DOFs for node 1 46 | % the number of DOFs for node 2 47 | % ... 48 | % the number of internal DOFs of the element 49 | Ke = [4 2 1 1 0]; 50 | return 51 | end 52 | 53 | global BOUNDARY_DATA 54 | 55 | Ke = zeros(2,2); 56 | Fe = zeros(2,1); 57 | Re = eye(2,2); 58 | Ve = BOUNDARY_DATA(1:2,k); 59 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/T3/dirichlet.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [Ke,Fe,Re,Ve] = dirichlet(k) 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | % 2D Convected Helmholtz Equation 20 | % Notation: exp(-i \omega t) 21 | % Boundary condition: dirichlet 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % Linear boundary element associated to the T3 element 24 | % 2 nodes 25 | % 2 DOFs: p1, p2 26 | % Data in ELEMENT(:,k) : 27 | % 1,2: node numbers 28 | % 3,4: coordinates along the boundary 29 | % 5: number of this boundary 30 | % 6: number of the neighboring element 31 | % 7: number of the side in the neighboring element 32 | % Data in ELEMENT_DATA(:,k): 33 | % None 34 | % Data in NODE_DATA(:,k): 35 | % None 36 | % Data in BOUNDARY_DATA(:,k): 37 | % 1: solution at node 1 38 | % 2: solution at node 2 39 | 40 | if nargin==0 41 | % Return the properties of the element 42 | % Ke should contain: 43 | % the priority of the element 44 | % the number of nodes 45 | % the number of DOFs for node 1 46 | % the number of DOFs for node 2 47 | % ... 48 | % the number of internal DOFs of the element 49 | Ke = [4 2 1 1 0]; 50 | return 51 | end 52 | 53 | global BOUNDARY_DATA 54 | 55 | Ke = zeros(2,2); 56 | Fe = zeros(2,1); 57 | Re = eye(2,2); 58 | Ve = BOUNDARY_DATA(1:2,k); 59 | -------------------------------------------------------------------------------- /Library/Potential_Flow_2D/T6/element.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = element(k) 2 | 3 | if nargin==0 4 | Ke = [1 6 1 1 1 1 1 1 0]; 5 | return 6 | end 7 | 8 | global Flow 9 | global U 10 | global ELEMENT NODE DOF_ELEMENT 11 | 12 | % Integration points on the triangle with vertices (0,0), (0,1) and (1,0) 13 | N_GAUSS_POINT = 7; 14 | GAUSS_POINT = [ 0.797426985353087 0.101286507323456 ; ... 15 | 0.101286507323456 0.797426985353087 ; ... 16 | 0.101286507323456 0.101286507323456 ; ... 17 | 0.059715871789770 0.470142064105115 ; ... 18 | 0.470142064105115 0.059715871789770 ; ... 19 | 0.470142064105115 0.470142064105115 ; ... 20 | 0.333333333333333 0.333333333333333 ]'; 21 | GAUSS_WEIGHT = [ 0.125939180544827 22 | 0.125939180544827 ; ... 23 | 0.125939180544827 ; ... 24 | 0.132394152788506 ; ... 25 | 0.132394152788506 ; ... 26 | 0.132394152788506 ; ... 27 | 0.225000000000000]'/2; 28 | 29 | % Node coordinates 30 | xn = NODE(1:2,ELEMENT(1:6,k))'; 31 | 32 | % Current solution 33 | phi = U(DOF_ELEMENT(1:6,k)); 34 | 35 | Ke = zeros(6); 36 | Fe = zeros(6, 1); 37 | 38 | for n=1:N_GAUSS_POINT 39 | u = GAUSS_POINT(1,n); 40 | v = GAUSS_POINT(2,n); 41 | w = 1-u-v; 42 | J = [ 1-4*w 4*(w-u) 4*u-1 4*v 0 -4*v ; ... 43 | 1-4*w -4*u 0 4*u 4*v-1 4*(w-v) ]*xn; 44 | detJ = det(J); 45 | GRAD = J\[ 1-4*w 4*(w-u) 4*u-1 4*v 0 -4*v ; ... 46 | 1-4*w -4*u 0 4*u 4*v-1 4*(w-v) ]; 47 | 48 | dphi = GRAD*phi; 49 | v2 = dphi(1)^2 + dphi(2)^2; 50 | rho = Flow.rho_inf*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 )^(1/(Flow.gamma-1)); 51 | c2 = Flow.c_inf^2*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 ); 52 | if v2>c2 53 | error('The flow is supersonic: the calculation cannot proceed (c=%f, v=%f).', sqrt(c2), sqrt(v2)); 54 | end 55 | Ke = Ke + GAUSS_WEIGHT(n)*( rho/c2*(dphi'*GRAD)'*(dphi'*GRAD) - rho*(GRAD'*GRAD) )*detJ; 56 | Fe = Fe + GAUSS_WEIGHT(n)*( rho*GRAD'*dphi )*detJ; 57 | end 58 | 59 | Re = zeros(6); 60 | Ve = zeros(6, 1); 61 | -------------------------------------------------------------------------------- /Core/PLOT_FEM.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function h = PLOT_FEM(node, element, A) 18 | % Plot a solution on a 2D finite element mesh 19 | % 20 | % node: a 2xN matrix where the rows corresponds to the coordinates and each 21 | % column corresponds to a node. 22 | % 23 | % element: a kxM matrix where k is the number of nodes per element and M is 24 | % the number of elements 25 | % 26 | % A: a vector of values. If A is of size N then it contains a value for 27 | % each node and an interpolation of this values is used over each element. 28 | % If A is of size M then it contains a value for each element and a 29 | % constant value is plotted in each element. 30 | % 31 | % If no argument A is provided then the mesh is plotted. 32 | % 33 | % If requested, this function returns a handle for the patch created in the 34 | % figure. 35 | 36 | X = node(1,:); 37 | Y = node(2,:); 38 | 39 | if nargin == 2 40 | hp = patch(X(element), Y(element), X(element)*0,'FaceColor','none'); 41 | elseif length(A) == size(node,2) 42 | hp = patch(X(element), Y(element), A(element), 'EdgeColor', 'none'); 43 | elseif length(A) == size(element,2) 44 | hp = patch(X(element), Y(element), A(:).', 'EdgeColor', 'none'); 45 | else 46 | error('Invalid input.'); 47 | end 48 | colormap('jet') 49 | 50 | if nargout == 1 51 | h = hp; 52 | end 53 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/T3/POST_mesh.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function out=POST_mesh(k) 18 | % k is the number of the domain to plot 19 | 20 | global ELEMENT NODE ELEMENT_DOMAIN 21 | 22 | % Return the name of the button shown in the GUI 23 | if nargin==0 24 | out = 'Mesh'; 25 | return 26 | end 27 | 28 | % List of the elements in the domain 29 | elem_list = find((ELEMENT_DOMAIN(1,:)==k)&(ELEMENT_DOMAIN(2,:)==0)); 30 | % List of the border elements in the domain 31 | border_list = find((ELEMENT_DOMAIN(1,:)==k)&(ELEMENT_DOMAIN(2,:)==1)); 32 | 33 | % Nodes coordinates 34 | X = NODE(1,:); 35 | Y = NODE(2,:); 36 | X = full(X(ELEMENT(1:3,elem_list))); 37 | Y = full(Y(ELEMENT(1:3,elem_list))); 38 | % Number of boundaries 39 | n_border = max(ELEMENT_DOMAIN(3,border_list)); 40 | 41 | figure 42 | flagmap = [0 0 1;0 1 0;1 0 0;1 1 0;0 1 1;1 0 1;0 0 0;1 1 1]; 43 | hold on 44 | patch(X,Y,ones(size(elem_list))*'b','EdgeColor',flagmap(1,:),'FaceColor','none'); 45 | for j=1:n_border 46 | X = NODE(1,:); 47 | Y = NODE(2,:); 48 | border_list = find((ELEMENT_DOMAIN(1,:)==k)&(ELEMENT_DOMAIN(2,:)==1)&(ELEMENT_DOMAIN(3,:)==j)); 49 | X = full(X(ELEMENT(1:2,border_list))); 50 | Y = full(Y(ELEMENT(1:2,border_list))); 51 | patch(X,Y,'w','EdgeColor',flagmap(j+1,:)); 52 | end 53 | hold off 54 | axis equal;axis tight; 55 | -------------------------------------------------------------------------------- /Library/Potential_Flow_3D/T4/element_matrixForm.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = element(k) 2 | % Compressible potential steady flow (3D) 3 | 4 | if nargin==0 5 | Ke = [1 4 1 1 1 1 0]; 6 | return 7 | end 8 | 9 | global Flow 10 | global U 11 | global ELEMENT NODE DOF_ELEMENT 12 | 13 | % Integration points on the tetrahedron with vertices 14 | % (0,0,0), (0,1,0), (1,0,0) and (0,0,1) 15 | N_GAUSS_POINT = 4; 16 | a = (5-sqrt(5))/20; b = (5+3*sqrt(5))/20; 17 | GAUSS_POINT = [ a a a b; a a b a; a b a a ]; 18 | GAUSS_WEIGHT = [1/24 1/24 1/24 1/24]; 19 | 20 | % Node coordinates 21 | x_node = NODE(1,ELEMENT(1:4,k)).'; 22 | y_node = NODE(2,ELEMENT(1:4,k)).'; 23 | z_node = NODE(3,ELEMENT(1:4,k)).'; 24 | 25 | % Current solution 26 | phi = U(DOF_ELEMENT(1:4,k)); 27 | 28 | Ke = zeros(4); 29 | Fe = zeros(4, 1); 30 | Re = zeros(4); 31 | Ve = zeros(4, 1); 32 | 33 | 34 | KeM = zeros(4); 35 | FeM = zeros(4, 1); 36 | 37 | % Assembly 38 | J = [-1 1 0 0 ; -1 0 1 0; -1 0 0 1]*[x_node y_node z_node]; 39 | detJ = det(J); 40 | GRAD = J\[-1 1 0 0 ; -1 0 1 0; -1 0 0 1]; 41 | 42 | for n=1:N_GAUSS_POINT 43 | %u = GAUSS_POINT(1,n); 44 | %v = GAUSS_POINT(2,n); 45 | %w = GAUSS_POINT(3,n); 46 | %************************ 47 | % N = [(1-u-v-w) u v w]; 48 | 49 | dphi = GRAD*phi; 50 | v2 = dphi(1)^2 + dphi(2)^2 + dphi(3)^2; 51 | rho = Flow.rho_inf*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 )^(1/(Flow.gamma-1)); 52 | c2 = Flow.c_inf^2*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 ); 53 | if v2>c2 54 | error('The flow is supersonic: the calculation cannot proceed (c=%f, v=%f).', sqrt(c2), sqrt(v2)); 55 | end 56 | % concise form 57 | %Ke = Ke + GAUSS_WEIGHT(n)*( rho/c2*(dphi'*GRAD)'*(dphi'*GRAD) - rho*(GRAD'*GRAD) )*detJ; 58 | %Fe = Fe + GAUSS_WEIGHT(n)*( rho*GRAD'*dphi )*detJ; 59 | 60 | % Matrix form 61 | STIF = GRAD.'*GRAD; 62 | PHI2 = phi*phi'; 63 | Ke = Ke + GAUSS_WEIGHT(n)*( rho/c2*STIF*PHI2*STIF - rho*STIF) *detJ; 64 | Fe = Fe + GAUSS_WEIGHT(n)*( rho*GRAD'*GRAD*phi )*detJ; 65 | end 66 | 67 | 68 | -------------------------------------------------------------------------------- /Library/Potential_Flow_Axi/T6/element.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = element(k) 2 | % Compressible potential steady flow 3 | % Axisymmetric flow 4 | % Cylindrical coordinates: z, r 5 | 6 | 7 | if nargin==0 8 | Ke = [1 6 1 1 1 1 1 1 0]; 9 | return 10 | end 11 | 12 | global Flow 13 | global U 14 | global ELEMENT NODE DOF_ELEMENT 15 | 16 | % Integration points on the triangle with vertices (0,0), (0,1) and (1,0) 17 | N_GAUSS_POINT = 7; 18 | GAUSS_POINT = [ 0.797426985353087 0.101286507323456 ; ... 19 | 0.101286507323456 0.797426985353087 ; ... 20 | 0.101286507323456 0.101286507323456 ; ... 21 | 0.059715871789770 0.470142064105115 ; ... 22 | 0.470142064105115 0.059715871789770 ; ... 23 | 0.470142064105115 0.470142064105115 ; ... 24 | 0.333333333333333 0.333333333333333 ]'; 25 | GAUSS_WEIGHT = [ 0.125939180544827 26 | 0.125939180544827 ; ... 27 | 0.125939180544827 ; ... 28 | 0.132394152788506 ; ... 29 | 0.132394152788506 ; ... 30 | 0.132394152788506 ; ... 31 | 0.225000000000000]'/2; 32 | 33 | % Node coordinates 34 | xn = NODE(1:2,ELEMENT(1:6,k))'; 35 | 36 | % Current solution 37 | phi = U(DOF_ELEMENT(1:6,k)); 38 | 39 | Ke = zeros(6); 40 | Fe = zeros(6, 1); 41 | 42 | for n=1:N_GAUSS_POINT 43 | u = GAUSS_POINT(1,n); 44 | v = GAUSS_POINT(2,n); 45 | w = 1-u-v; 46 | J = [ 1-4*w 4*(w-u) 4*u-1 4*v 0 -4*v ; ... 47 | 1-4*w -4*u 0 4*u 4*v-1 4*(w-v) ]*xn; 48 | detJ = det(J); 49 | GRAD = J\[ 1-4*w 4*(w-u) 4*u-1 4*v 0 -4*v ; ... 50 | 1-4*w -4*u 0 4*u 4*v-1 4*(w-v) ]; 51 | N = [ (2*w-1)*w 4*u*w (2*u-1)*u 4*u*v (2*v-1)*v 4*v*w ]; 52 | r = N*xn(:,2); 53 | 54 | dphi = GRAD*phi; 55 | v2 = dphi(1)^2 + dphi(2)^2; 56 | rho = Flow.rho_inf*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 )^(1/(Flow.gamma-1)); 57 | c2 = Flow.c_inf^2*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 ); 58 | if v2>c2 59 | warning('The flow is supersonic: the calculation cannot proceed (c=%f, v=%f).', sqrt(c2), sqrt(v2)); 60 | end 61 | Ke = Ke + GAUSS_WEIGHT(n)*( rho/c2*(dphi'*GRAD)'*(dphi'*GRAD) - rho*(GRAD'*GRAD) )*r*detJ; 62 | Fe = Fe + GAUSS_WEIGHT(n)*( rho*GRAD'*dphi )*r*detJ; 63 | end 64 | 65 | Re = zeros(6); 66 | Ve = zeros(6, 1); 67 | -------------------------------------------------------------------------------- /Core/CREATE_INTERFACE_ELEMENTS.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function CREATE_INTERFACE_ELEMENTS(d, g, ng) 18 | % Create a new group of elements corresponding to interfaces between 19 | % existing elements 20 | % d: domain number of the elements to process 21 | % g: a vector of group numbers that should be processed 22 | % ng: the number of the new group of interface elements 23 | 24 | global ELEMENT N_NODE_ELEMENT N_ELEMENT 25 | global ELEMENT_ID ELEMENT_DOMAIN 26 | 27 | ne = GET_ELEMENT_LIST(d, 0, g); 28 | 29 | % Table of nodes per element 30 | e_ = ELEMENT(1:3, ne ); 31 | % Table of element edges 32 | segment = [e_(1:2,:) e_(2:3,:) [e_(3,:);e_(1,:)]]; 33 | % Table mapping edge into original elements 34 | seg_elem = [(1:size(e_,2)) (1:size(e_,2)) (1:size(e_,2))]; 35 | % Construct the matrix of connectivity between nodes 36 | temp = sparse(segment(1,:),segment(2,:),seg_elem); 37 | % Remove edges which are not double sided (remove boundary elements) 38 | temp = temp .* ((temp~=0).*(temp.'~=0)); 39 | % Extract the connectivity between nodes 40 | [ii,jj,ss] = find(temp); 41 | s_ = [ii' ; jj' ; ne(ss)]; 42 | [ii,jj,ss] = find(temp.'); 43 | s_ = [s_ ; ne(ss)]; 44 | % Remove the duplicated edges 45 | s_ = s_(:, s_(3,:)>s_(4,:) ); 46 | % Update the finite element model 47 | ns_ = size(s_,2); 48 | % Update the database 49 | ELEMENT = [[ELEMENT;zeros(size(s_,1)-size(ELEMENT,1),N_ELEMENT)] s_]; 50 | N_NODE_ELEMENT = [N_NODE_ELEMENT s_(1,:)*0+2]; 51 | N_ELEMENT = N_ELEMENT + ns_; 52 | ELEMENT_ID = [ELEMENT_ID s_(1,:)*0]; 53 | ELEMENT_DOMAIN = [ELEMENT_DOMAIN [d;0;ng]*ones(1,ns_)]; 54 | -------------------------------------------------------------------------------- /Core/METHOD_FEM.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | % Standard FEM assembling function 18 | % list: a vector containing the list of the numbers of the elements that 19 | % are part of the current domain. 20 | 21 | fprintf('METHOD_FEM: Domain %i (%i elements)\n',ELEMENT_DOMAIN(1,list(1)),length(list)); 22 | % Calculate the maximum number of non-zero entries 23 | nnzK = sum(N_DOF_ELEMENT(list).^2); 24 | % Prepare temporary storage for the non-zero entries 25 | ii = ones(nnzK,1); 26 | jj = ii; 27 | ss = zeros(nnzK,1); 28 | aa = 0; 29 | % Loop over the elements 30 | for j=1:length(list) 31 | % Call the element function 32 | [Ke,Fe,Re,Ve] = feval(char(ELEMENT_NAME(ELEMENT_LIST(list(j)))),list(j)); 33 | % The list of DOFs for the current element 34 | dof_list = DOF_ELEMENT(1:N_DOF_ELEMENT(list(j)),list(j)); 35 | % Store the entries for the matrix 36 | [iie,jje,sse] = find(Ke); 37 | if ~isempty(iie) 38 | aa = aa(end) + (1:length(iie)); 39 | ii(aa) = dof_list(iie); 40 | jj(aa) = dof_list(jje); 41 | ss(aa) = sse; 42 | end 43 | % Store the contributions to the RHS (multi-rhs possible) 44 | F(dof_list,:) = F(dof_list,:) + Fe; 45 | % Store the linear constraints 46 | Le = find(max(abs(Re),[],2)); 47 | % Clean up any previous linear constraints 48 | % R(dof_list(Le),:) = 0; 49 | % R(dof_list(Le),dof_list) = Re(Le,:); 50 | % V(dof_list(Le)) = Ve(Le); 51 | % Add up the linear constraints 52 | R(dof_list(Le),dof_list) = R(dof_list(Le),dof_list) + Re(Le,:); 53 | V(dof_list(Le)) = V(dof_list(Le)) + Ve(Le); 54 | end 55 | % Perform the assembling 56 | K = K + sparse(ii,jj,ss,N_DOF,N_DOF); 57 | 58 | % Tidy up the workspace 59 | clear ii jj ss iie jje sse Le Fe Ke Re Ve aa 60 | -------------------------------------------------------------------------------- /Library/Potential_Flow_2D/T6/velocity.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = velocity(k) 2 | 3 | if nargin==0 4 | Ke = [4 3 1 1 1 0]; 5 | return 6 | end 7 | 8 | global U 9 | global ELEMENT NODE DOF_ELEMENT 10 | global BOUNDARY_DATA 11 | global Flow 12 | 13 | Ke = zeros(6); 14 | Fe = zeros(6, 1); 15 | Re = zeros(6); 16 | Ve = zeros(6, 1); 17 | 18 | % Integration points on [-1;+1] 19 | N_GAUSS_POINT = 7; 20 | a0 = 0; 21 | a1 = 0.405845151377397; 22 | a2 = 0.741531185599394; 23 | a3 = 0.949107912342759; 24 | c0 = 0.417959183673469; 25 | c1 = 0.381830050505119; 26 | c2 = 0.279705391489277; 27 | c3 = 0.129484966168870; 28 | GAUSS_POINT = [a0 -a1 a1 -a2 a2 -a3 a3]; 29 | GAUSS_WEIGHT = [c0 c1 c1 c2 c2 c3 c3]; 30 | 31 | % Node coordinates 32 | xn = NODE(1:2, ELEMENT(1:6, k))'; 33 | 34 | % Current solution 35 | phi = U(DOF_ELEMENT(1:6,k)); 36 | 37 | % Imposed normal velocity 38 | V = BOUNDARY_DATA(1:3,k); 39 | 40 | for n=1:N_GAUSS_POINT 41 | % Use the neighboring T6 element to calculate the velocity 42 | % Scale the coordinates because we use T6 shape functions defined on 43 | % the triangle between the vertices (0,0), (0,1) and (1,0). 44 | u = (GAUSS_POINT(n)+1)/2; 45 | v = 0; 46 | w = 1-u-v; 47 | J = [ 1-4*w 4*(w-u) 4*u-1 4*v 0 -4*v ; ... 48 | 1-4*w -4*u 0 4*u 4*v-1 4*(w-v) ]*xn; 49 | GRAD = J\[ 1-4*w 4*(w-u) 4*u-1 4*v 0 -4*v ; ... 50 | 1-4*w -4*u 0 4*u 4*v-1 4*(w-v) ]; 51 | dphi = GRAD*phi; 52 | v2 = dphi(1)^2 + dphi(2)^2; 53 | rho = Flow.rho_inf*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 )^(1/(Flow.gamma-1)); 54 | c2 = Flow.c_inf^2*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 ); 55 | if v2>c2 56 | error('The flow is supersonic: the calculation cannot proceed (c=%f, v=%f).', sqrt(c2), sqrt(v2)); 57 | end 58 | 59 | % L3 shape functions on [-1;+1] 60 | u = GAUSS_POINT(n); 61 | L = [-u*(1-u)/2 (1-u^2) u*(1+u)/2]; 62 | Lu = [-1+2*u -4*u 1+2*u]/2; 63 | xs = Lu*xn(1:3, 1); 64 | ys = Lu*xn(1:3, 2); 65 | Js = sqrt(xs^2+ys^2); 66 | GRAD = Lu/Js; 67 | % Tangential vector 68 | tx = xs/Js; 69 | ty = ys/Js; 70 | % Gradients of the current solution in the tangential and normal 71 | % directions 72 | dphi_t = dphi(1)*tx + dphi(2)*ty; 73 | dphi_n = dphi(1)*ty - dphi(2)*tx; 74 | 75 | Ke(1:3,1:3) = Ke(1:3,1:3) + GAUSS_WEIGHT(n)*( rho/c2*(L*V)*dphi_t*L'*GRAD )*Js; 76 | Fe(1:3) = Fe(1:3) + GAUSS_WEIGHT(n)*( -rho*L'*(L*V) + rho/c2*(L*V)*dphi_n*((L*V)-dphi_n)*L' )*Js; 77 | end 78 | -------------------------------------------------------------------------------- /Core/POST_PROCESS.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | % Provide a simple GUI to select what is shown on screen 18 | 19 | % The prefix of the post-processing functions 20 | FILE_ID = 'POST_'; 21 | 22 | namelist = cell(N_DOMAIN,1); 23 | domainname = cell(N_DOMAIN+1,1); 24 | filename = cell(N_DOMAIN+1,1); 25 | for k=1:N_DOMAIN 26 | domainname{k} = ['Domain' num2str(k)]; 27 | addpath(DOMAIN_PATH{k}) 28 | names = dir(DOMAIN_PATH{k}); 29 | n = size(names); 30 | number = 0; 31 | for j=1:n 32 | if (~names(j).isdir)&strncmp(names(j).name,FILE_ID,size(FILE_ID,2)) 33 | number = number+1; 34 | LIST(number) = j; 35 | end 36 | end 37 | namelist{k} = cell(number+2,1); 38 | filename{k} = cell(number,1); 39 | for j=1:number 40 | temp = names(LIST(j)).name; 41 | filename{k}{j} = temp(1:end-2); 42 | namelist{k}{j} = feval(temp(1:end-2)); 43 | end 44 | namelist{k}{number+1} = 'BACK'; 45 | namelist{k}{number+2} = 'END'; 46 | rmpath(DOMAIN_PATH{k}) 47 | end 48 | domainname{N_DOMAIN+1} = 'END'; 49 | 50 | A = 1; 51 | while A==1 52 | a = menu('Post Processing',domainname); 53 | if a==N_DOMAIN+1 54 | A = 0; 55 | else 56 | addpath(DOMAIN_PATH{a}) 57 | B = 1; 58 | while B==1 59 | b = menu(domainname{a},namelist{a}); 60 | if b==length(namelist{a}) 61 | A = 0; 62 | B = 0; 63 | end 64 | if b==length(namelist{a})-1 65 | B = 0; 66 | end 67 | if bc2 56 | error('The flow is supersonic: the calculation cannot proceed (c=%f, v=%f).', sqrt(c2), sqrt(v2)); 57 | end 58 | 59 | % L3 shape functions on [-1;+1] 60 | u = GAUSS_POINT(n); 61 | L = [-u*(1-u)/2 (1-u^2) u*(1+u)/2]; 62 | Lu = [-1+2*u -4*u 1+2*u]/2; 63 | xs = Lu*xn(1:3, 1); 64 | ys = Lu*xn(1:3, 2); 65 | Js = sqrt(xs^2+ys^2); 66 | GRAD = Lu/Js; 67 | % Tangential vector 68 | tx = xs/Js; 69 | ty = ys/Js; 70 | % Gradients of the current solution in the tangential and normal 71 | % directions 72 | dphi_t = dphi(1)*tx + dphi(2)*ty; 73 | dphi_n = dphi(1)*ty - dphi(2)*tx; 74 | 75 | r = L*xn(1:3,2); 76 | 77 | Ke(1:3,1:3) = Ke(1:3,1:3) + GAUSS_WEIGHT(n)*( rho/c2*(L*V)*dphi_t*L'*GRAD )*r*Js; 78 | Fe(1:3) = Fe(1:3) + GAUSS_WEIGHT(n)*( -rho*L'*(L*V) + rho/c2*(L*V)*dphi_n*((L*V)-dphi_n)*L' )*r*Js; 79 | end 80 | -------------------------------------------------------------------------------- /Library/Potential_Flow_Axi/T6/mach.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = mach(k) 2 | 3 | if nargin==0 4 | Ke = [4 3 1 1 1 0]; 5 | return 6 | end 7 | 8 | global U 9 | global ELEMENT NODE DOF_ELEMENT 10 | global BOUNDARY_DATA 11 | global Flow 12 | 13 | Ke = zeros(6); 14 | Fe = zeros(6, 1); 15 | Re = zeros(6); 16 | Ve = zeros(6, 1); 17 | 18 | % Integration points on [-1;+1] 19 | N_GAUSS_POINT = 7; 20 | a0 = 0; 21 | a1 = 0.405845151377397; 22 | a2 = 0.741531185599394; 23 | a3 = 0.949107912342759; 24 | c0 = 0.417959183673469; 25 | c1 = 0.381830050505119; 26 | c2 = 0.279705391489277; 27 | c3 = 0.129484966168870; 28 | GAUSS_POINT = [a0 -a1 a1 -a2 a2 -a3 a3]; 29 | GAUSS_WEIGHT = [c0 c1 c1 c2 c2 c3 c3]; 30 | 31 | % Node coordinates 32 | xn = NODE(1:2, ELEMENT(1:6, k))'; 33 | 34 | % Current solution 35 | phi = U(DOF_ELEMENT(1:6,k)); 36 | 37 | % Imposed normal velocity 38 | Mach = BOUNDARY_DATA(1:3,k); 39 | 40 | for n=1:N_GAUSS_POINT 41 | % Use the neighboring T6 element to calculate the velocity 42 | % Scale the coordinates because we use T6 shape functions defined on 43 | % the triangle between the vertices (0,0), (0,1) and (1,0). 44 | u = (GAUSS_POINT(n)+1)/2; 45 | v = 0; 46 | w = 1-u-v; 47 | J = [ 1-4*w 4*(w-u) 4*u-1 4*v 0 -4*v ; ... 48 | 1-4*w -4*u 0 4*u 4*v-1 4*(w-v) ]*xn; 49 | GRAD = J\[ 1-4*w 4*(w-u) 4*u-1 4*v 0 -4*v ; ... 50 | 1-4*w -4*u 0 4*u 4*v-1 4*(w-v) ]; 51 | dphi = GRAD*phi; 52 | v2 = dphi(1)^2 + dphi(2)^2; 53 | rho = Flow.rho_inf*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 )^(1/(Flow.gamma-1)); 54 | c2 = Flow.c_inf^2*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 ); 55 | if v2>c2 56 | error('The flow is supersonic: the calculation cannot proceed (c=%f, v=%f).', sqrt(c2), sqrt(v2)); 57 | end 58 | c = sqrt(c2); 59 | 60 | % L3 shape functions on [-1;+1] 61 | u = GAUSS_POINT(n); 62 | L = [-u*(1-u)/2 (1-u^2) u*(1+u)/2]; 63 | Lu = [-1+2*u -4*u 1+2*u]/2; 64 | xs = Lu*xn(1:3, 1); 65 | ys = Lu*xn(1:3, 2); 66 | Js = sqrt(xs^2+ys^2); 67 | GRAD = Lu/Js; 68 | % Tangential vector 69 | tx = xs/Js; 70 | ty = ys/Js; 71 | % Gradients of the current solution in the tangential and normal 72 | % directions 73 | dphi_t = dphi(1)*tx + dphi(2)*ty; 74 | dphi_n = dphi(1)*ty - dphi(2)*tx; 75 | 76 | r = L*xn(1:3,2); 77 | M = L*Mach; 78 | 79 | Ke(1:3,1:3) = Ke(1:3,1:3) + GAUSS_WEIGHT(n)*( rho*M*dphi_t/c*L'*GRAD )*r*Js; 80 | Fe(1:3) = Fe(1:3) + GAUSS_WEIGHT(n)*( -rho*L'*M*c + rho*M*dphi_n*(M-dphi_n/c)*L' )*r*Js; 81 | end 82 | -------------------------------------------------------------------------------- /Core/BUILD_SYSTEM.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | % This script drives the assembly of the global system 18 | 19 | % Initialise an empty sparse matrix for the global matrix 20 | K = sparse(N_DOF,N_DOF); 21 | % Initialise an empty sparse vector for the right-hand side 22 | F = sparse(N_DOF,N_RHS); 23 | % Initialise an empty sparse matrix for the linear constraints 24 | R = sparse(N_DOF,N_DOF); 25 | % Initialise an empty sparse vector for the linear constraints 26 | V = sparse(N_DOF,1); 27 | % Loop over the domains 28 | for k=1:N_DOMAIN 29 | % Create a list of the elements in the current domain 30 | list = find(ELEMENT_DOMAIN(1,:)==k); %#ok 31 | % Add the path to the element functions for this domain 32 | for iPath = 1:length(LIBRARY_PATH) 33 | if (exist(DOMAIN_PATH{iPath,k},'dir')) 34 | addpath(DOMAIN_PATH{iPath,k}); 35 | end 36 | end 37 | % Launch the assembly script for this domain 38 | eval(char(DOMAIN_METHOD{k,k})); 39 | % Go through possible couplings with other domains 40 | for j=1:N_DOMAIN 41 | % Check if the domain k and j are coupled 42 | if ~isempty(INTERFACE{k,j}) 43 | % Create the list of interactions between elements of the two 44 | % domains 45 | list = INTERFACE{k,j}; %#ok 46 | if size(list,1)==1; 47 | list = list.'; 48 | end 49 | % Launch the script to calculate the interaction 50 | eval(char(DOMAIN_METHOD{k,j})); 51 | end 52 | end 53 | % Remove the path to the element functions for this domain 54 | for iPath = 1:length(LIBRARY_PATH) 55 | if (exist(DOMAIN_PATH{iPath,k},'dir')) 56 | rmpath(DOMAIN_PATH{iPath,k}); 57 | end 58 | end 59 | end 60 | 61 | % Remove temporary variables 62 | clear list k j 63 | -------------------------------------------------------------------------------- /Core/create_subT3.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [u,v,c] = create_subT3(N) 18 | % Create a set of nodes and small triangular elements covering the 19 | % reference triangular element (with 0. 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | global LIBRARY_PATH 17 | 18 | DIRECTORY = fullfile('Code_FEM','Core'); 19 | 20 | % Get the directories in the path 21 | P = path; 22 | numbers = find(P==pathsep); 23 | for k=0:length(numbers) 24 | if k==0 25 | token = P(1:(numbers(1)-1)); 26 | end 27 | if k==length(numbers) 28 | token = P((numbers(k)+1):end); 29 | end 30 | if (k>0)&&(k0)&&(kc2 63 | error('The flow is supersonic: the calculation cannot proceed (c=%f, v=%f).', sqrt(c2), sqrt(v2)); 64 | end 65 | 66 | % T3 shape functions 67 | u = GAUSS_POINT(1,n); 68 | v = GAUSS_POINT(2,n); 69 | % 70 | L = [1-u-v u v]; 71 | X_tria = L*NODE(1:3,ELEMENT(1:3,k)).'; 72 | if norm(X_tetra-X_tria)>100*eps 73 | error('Problem in velocity!') 74 | end 75 | 76 | % Gradients of the current solution in the normal direction 77 | dphi_n = dphi(1)*no(1) + dphi(2)*no(2) + dphi(3)*no(3); 78 | 79 | % normal gradient 80 | Gn = GRAD(1,:)*no(1) + GRAD(2,:)*no(2) + GRAD(3,:)*no(3); 81 | 82 | % local prescribed velocity 83 | V = L*Vnodes; 84 | 85 | Ke(1:4,1:4) = Ke(1:4,1:4) + GAUSS_WEIGHT(n)*( rho/c2*V*N.'*( dphi*GRAD - dphi_n*Gn ) )*Js; 86 | Fe(1:4) = Fe(1:4) + GAUSS_WEIGHT(n)*( -rho*N'*V + rho/c2*N.'*V*dphi_n*(V-dphi_n) )*Js; 87 | end -------------------------------------------------------------------------------- /Library/Helmholtz_2D/Q4/wall.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [Ke,Fe,Re,Ve] = wall(k) 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | % 2D Convected Helmholtz Equation 20 | % Notation: exp(-i \omega t) 21 | % Boundary condition: imposed normal velocity 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % Linear boundary element associated to the T3 element 24 | % 2 nodes 25 | % 2 DOFs: p1, p2 26 | % Data in ELEMENT(:,k) : 27 | % 1,2: node numbers 28 | % 3,4: coordinates along the boundary 29 | % 5: number of this boundary 30 | % 6: number of the neighboring element 31 | % 7: number of the side in the neighboring element 32 | % Data in ELEMENT_DATA(:,k): 33 | % None 34 | % Data in NODE_DATA(:,k): 35 | % None 36 | % Data in BOUNDARY_DATA(:,k): 37 | % 1: acceleration at node 1 38 | % 2: acceleration at node 2 39 | 40 | if nargin==0 41 | % Return the properties of the element 42 | % Ke should contain: 43 | % the priority of the element 44 | % the number of nodes 45 | % the number of DOFs for node 1 46 | % the number of DOFs for node 2 47 | % ... 48 | % the number of internal DOFs of the element 49 | Ke = [4 2 1 1 0]; 50 | return 51 | end 52 | 53 | global ELEMENT NODE NODE_DATA BOUNDARY_DATA 54 | 55 | C0 = NODE_DATA(2,ELEMENT(1,k)); 56 | 57 | Ke = zeros(2,2); 58 | Fe = zeros(2,1); 59 | Re = zeros(2,2); 60 | Ve = zeros(2,1); 61 | 62 | N_GAUSS_POINT = 2; 63 | GAUSS_POINT = [1 -1]/sqrt(3); 64 | GAUSS_WEIGHT = [1 1]; 65 | 66 | x_point = NODE(1,ELEMENT(1:2,k))'; 67 | y_point = NODE(2,ELEMENT(1:2,k))'; 68 | 69 | % Imposed accelerations at the nodes 70 | a1 = BOUNDARY_DATA(1,k); 71 | a2 = BOUNDARY_DATA(2,k); 72 | 73 | for n=1:N_GAUSS_POINT 74 | % Coordinate of the Gauss point on the reference elements 75 | u = GAUSS_POINT(n); 76 | % Shape functions for the solution 77 | L = [1-u 1+u]/2; 78 | % Shape functions for the gradient of the solution 79 | Lu = [-1 1]/2; 80 | % Jacobian to the physical element 81 | Js = sqrt((Lu*x_point)^2+(Lu*y_point)^2); 82 | % Add contribution to the right-hand side 83 | Fe = Fe + GAUSS_WEIGHT(n)*( C0^2*(L'*L)*[a1;a2] )*Js; 84 | end 85 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D_BEM/DiffractionByPlaneWave/main.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | % To find the solver 17 | addpath('../../../../Code_FEM/Core'); 18 | MANAGE_PATH 19 | 20 | global omega typegeo type Order 21 | global alpha beta % Burton Miller formulation 22 | global N_GAUSS_POINT GAUSS_POINT GAUSS_WEIGHT 23 | global SHAPEFUNC DSHAPEFUNC 24 | 25 | % Diffraction of a circle by an incident Plane Wave 26 | 27 | %%%%%%%%%% Plane wave Excitation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | 29 | % Type of geometry 30 | typegeo = 'circle'; 31 | Perimeter = 2*pi; 32 | % Plane wave amplitude 33 | Ainc = 1; 34 | % Frequency 35 | ka = 3.2; 36 | omega = ka*340; 37 | % Interpolation order 38 | Order = 3; 39 | % Fixed Number of BEM elements 40 | Nelement = 10; 41 | % Or based on a dof density 42 | % ndof = 400; 43 | % Nelement = round(ndof*Perimeter*(ka/(2*pi))/Order); 44 | % Number of Gauss Points per wavelength 45 | NGPWL = 10; 46 | % Burton and Miller 47 | if strcmp(type,'open') 48 | alpha = 1; beta = 0; 49 | else 50 | alpha= 1i/ka; beta = 1; 51 | end 52 | % Mesh creation 53 | INIT_GEOMETRY 54 | [N_DIM,N_NODE,NODE,N_ELEMENT,N_NODE_ELEMENT,ELEMENT,N_DOMAIN... 55 | ,ELEMENT_DOMAIN,NODE_DOMAIN,ELEMENT_ID,NODE_ID] = feval('geobem',Nelement,Order); 56 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 57 | % Compute the element length 58 | LENGTH_ELEMENT = ElementLength(Order); 59 | ndofpwl = (N_NODE)/((sum(LENGTH_ELEMENT))/(2*pi/ka)); 60 | % Precompute the shape functions at the Gauss points 61 | N_GAUSS_POINT = max(max(ceil(LENGTH_ELEMENT*ka/(2*pi)*NGPWL),4)); 62 | [GAUSS_POINT,GAUSS_WEIGHT] = gauleg(-1,1,N_GAUSS_POINT); 63 | SHAPEFUNC = zeros(Order+1,N_GAUSS_POINT); 64 | DSHAPEFUNC = zeros(Order+1,N_GAUSS_POINT); 65 | for n=1:N_GAUSS_POINT 66 | [Nu,dNu]=shape_function(GAUSS_POINT(n),Order); 67 | SHAPEFUNC(:,n)=Nu; 68 | DSHAPEFUNC(:,n)=dNu; 69 | end 70 | fprintf('\n Numerical data: \n ka = %i, %1.2f dof per wavelength, Order of interp. = %i \n \n',ka,ndofpwl,Order); 71 | 72 | BUILD_MODEL 73 | BUILD_DOF 74 | BUILD_SYSTEM 75 | SOLVE_SYSTEM 76 | 77 | [Uanal] = CirclePlanewave_AnalyticalSolution(NODE,1); 78 | ErL2 = L2Error(U,Uanal); 79 | fprintf('L2 error: %g pc \n', ErL2); 80 | 81 | % plot the result 82 | PlotResults -------------------------------------------------------------------------------- /Library/Helmholtz_2D/T3/wall.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [Ke,Fe,Re,Ve] = wall(k) 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | % 2D Convected Helmholtz Equation 20 | % Notation: exp(-i \omega t) 21 | % Boundary condition: imposed normal velocity 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % Linear boundary element associated to the T3 element 24 | % 2 nodes 25 | % 2 DOFs: p1, p2 26 | % Data in ELEMENT(:,k) : 27 | % 1,2: node numbers 28 | % 3,4: coordinates along the boundary 29 | % 5: number of this boundary 30 | % 6: number of the neighboring element 31 | % 7: number of the side in the neighboring element 32 | % Data in ELEMENT_DATA(:,k): 33 | % None 34 | % Data in NODE_DATA(:,k): 35 | % None 36 | % Data in BOUNDARY_DATA(:,k): 37 | % 1: acceleration at node 1 38 | % 2: acceleration at node 2 39 | 40 | if nargin==0 41 | % Return the properties of the element 42 | % Ke should contain: 43 | % the priority of the element 44 | % the number of nodes 45 | % the number of DOFs for node 1 46 | % the number of DOFs for node 2 47 | % ... 48 | % the number of internal DOFs of the element 49 | Ke = [4 2 1 1 0]; 50 | return 51 | end 52 | 53 | global ELEMENT NODE NODE_DATA BOUNDARY_DATA 54 | 55 | C0 = NODE_DATA(2,ELEMENT(1,k)); 56 | 57 | Ke = zeros(2,2); 58 | Fe = zeros(2,1); 59 | Re = zeros(2,2); 60 | Ve = zeros(2,1); 61 | 62 | N_GAUSS_POINT = 2; 63 | GAUSS_POINT = [1 -1]/sqrt(3); 64 | GAUSS_WEIGHT = [1 1]; 65 | 66 | x_point = NODE(1,ELEMENT(1:2,k))'; 67 | y_point = NODE(2,ELEMENT(1:2,k))'; 68 | 69 | % Imposed accelerations at the nodes 70 | a1 = BOUNDARY_DATA(1,k); 71 | a2 = BOUNDARY_DATA(2,k); 72 | 73 | for n=1:N_GAUSS_POINT 74 | % Coordinate of the Gauss point on the reference elements 75 | u = GAUSS_POINT(n); 76 | % Shape functions for the solution 77 | L = [1-u 1+u]/2; 78 | % Shape functions for the gradient of the solution 79 | Lu = [-1 1]/2; 80 | % Jacobian to the physical element 81 | Js = sqrt((Lu*x_point)^2+(Lu*y_point)^2); 82 | % Add contribution to the right-hand side 83 | Fe = Fe + GAUSS_WEIGHT(n)*( C0^2*(L'*L)*[a1;a2] )*Js; 84 | end 85 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D_BEM/DiffractionByPlaneWave/geobem.m: -------------------------------------------------------------------------------- 1 | function [n_dim,n_node,node,n_element,n_node_element,element,n_domain,element_domain,node_domain,element_ID,node_ID] = geobem(n_element,Order) 2 | 3 | global typegeo type 4 | 5 | % Generates a BEM 2D geometry 6 | % Order designates the interpolation order (Lagrange) 7 | 8 | % Number of central nodes 9 | Nc = Order-1; 10 | 11 | % Number of nodes 12 | n_node = n_element*(Nc+1); 13 | 14 | % Angle parametrization 15 | t = linspace(0,2*pi,n_node+1); t = t(1:end-1); 16 | 17 | switch typegeo 18 | % CLOSED BOUNDARIES 19 | case 'circle' 20 | type = 'closed'; 21 | X = cos(t); 22 | Y = sin(t); 23 | case 'ellipse' 24 | type = 'closed'; 25 | a = 2; b = 1; 26 | X = a*cos(t); Y = b*sin(t); 27 | case 'boomerang' 28 | type = 'closed'; 29 | X = (cos(t)+10*cos(2*t)-10)/10; 30 | Y = sin(t); 31 | case 'star' 32 | type = 'closed'; 33 | X = cos(t).*(1+0.5*cos(10*t)); 34 | Y = sin(t).*(1+0.5*cos(10*t)); 35 | case 'square' 36 | type = 'closed'; 37 | if (n_element/4)~=round(n_element/4)% 38 | fprintf('Multiple of 4 is preffered'); 39 | n_element = round(n_element/4)*4; 40 | n_node = n_element*(Nc+1); 41 | end 42 | L = 2; 43 | nnc = n_node/4; 44 | X(1:nnc) = (L/2)-L/(nnc)*(0:nnc-1); Y(1:nnc) = 1; 45 | X(nnc+1:2*nnc) = -1; Y(nnc+1:2*nnc) = (L/2)-L/(nnc)*(0:nnc-1); 46 | X(2*nnc+1:3*nnc) = -(L/2)+L/(nnc)*(0:nnc-1); Y(2*nnc+1:3*nnc) = -1; 47 | X(3*nnc+1:4*nnc) = 1; Y(3*nnc+1:4*nnc) = -(L/2)+L/(nnc)*(0:nnc-1); 48 | 49 | % OPEN BOUNDARIES 50 | case 'circlearc' 51 | type = 'open'; 52 | n_node = n_node+1; 53 | th = linspace(pi/2,3*pi/2,n_node); 54 | X = cos(th); 55 | Y = sin(th); 56 | 57 | case 'plate' 58 | type = 'open'; 59 | n_node = n_node+1; 60 | L = 2; 61 | Y(1:n_node) = (L/(n_node-1)*(0:n_node-1))-L/2; X(1:n_node) = 0; 62 | 63 | case 'spiral' 64 | type = 'open'; 65 | n_node = n_node+1; 66 | t = linspace(0,2*pi,n_node); 67 | X = (t.*cos(2*t))/(2*pi); 68 | Y = (t.*sin(2*t))/(2*pi); 69 | 70 | otherwise 71 | error('Geometry not defined'); 72 | end 73 | 74 | node(1,:) = X; 75 | node(2,:) = Y; 76 | n_node_element = Nc+2; 77 | 78 | % Connectivity creation 79 | element(1,:) = 1:Nc+1:n_node-Nc; 80 | for n=2:n_node_element 81 | element(n,:) = element(n-1,:)+1; 82 | end 83 | if (strcmp(type,'open')==0) 84 | element(n_node_element(end),end) = element(1,1); 85 | end 86 | 87 | n_dim = 2; 88 | n_domain = 1; 89 | element_domain = [ones(1,n_element); zeros(1,n_element); ones(1,n_element)] ; % QUE DES elementS DE DOMAINE 90 | node_domain = ones(1,n_node); 91 | element_ID = 1:n_element; 92 | node_ID = 1:n_node; 93 | n_node_element = n_node_element+zeros(1,n_element); 94 | 95 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/Q4/impedance.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [Ke,Fe,Re,Ve] = impedance(k) 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | % 2D Convected Helmholtz Equation 20 | % Notation: exp(-i \omega t) 21 | % Boundary condition: impedance 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % Linear boundary element associated to the T3 element 24 | % 2 nodes 25 | % 2 DOFs: p1, p2 26 | % Data in ELEMENT(:,k) : 27 | % 1,2: node numbers 28 | % 3,4: coordinates along the boundary 29 | % 5: number of this boundary 30 | % 6: number of the neighboring element 31 | % 7: number of the side in the neighboring element 32 | % Data in ELEMENT_DATA(:,k): 33 | % None 34 | % Data in NODE_DATA(:,k): 35 | % None 36 | % Data in BOUNDARY_DATA(:,k): 37 | % 1: impedance at node 1 38 | % 2: impedance at node 2 39 | 40 | if nargin==0 41 | % Return the properties of the element 42 | % Ke should contain: 43 | % the priority of the element 44 | % the number of nodes 45 | % the number of DOFs for node 1 46 | % the number of DOFs for node 2 47 | % ... 48 | % the number of internal DOFs of the element 49 | Ke = [5 2 1 1 0]; 50 | return 51 | end 52 | 53 | global omega 54 | global ELEMENT NODE NODE_DATA BOUNDARY_DATA 55 | 56 | RHO = NODE_DATA(1,ELEMENT(1,k)); 57 | C0 = NODE_DATA(2,ELEMENT(1,k)); 58 | 59 | % Boundary condition values (impedance Z) 60 | Z1 = BOUNDARY_DATA(1,k); 61 | Z2 = BOUNDARY_DATA(2,k); 62 | 63 | Ke = zeros(2,2); 64 | Fe = zeros(2,1); 65 | Re = zeros(2,2); 66 | Ve = zeros(2,1); 67 | 68 | N_GAUSS_POINT = 2; 69 | GAUSS_POINT = [1 -1]/sqrt(3); 70 | GAUSS_WEIGHT = [1 1]; 71 | 72 | x_point = NODE(1,ELEMENT(1:2,k))'; 73 | y_point = NODE(2,ELEMENT(1:2,k))'; 74 | 75 | for n=1:N_GAUSS_POINT 76 | % Coordinate of the Gauss point on the reference elements 77 | u = GAUSS_POINT(n); 78 | % Shape functions for the solution 79 | L = [1-u 1+u]/2; 80 | % Shape functions for the gradient of the solution 81 | Lu = [-1 1]/2; 82 | % Jacobian to the physical element 83 | Js = sqrt((Lu*x_point)^2+(Lu*y_point)^2); 84 | % Interpolate the impedance 85 | Z = L*[Z1;Z2]; 86 | % Add contribution to the element matrix 87 | Ke = Ke + GAUSS_WEIGHT(n)*( -1i*omega*RHO*C0^2/Z*(L'*L) )*Js; 88 | end 89 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/T3/impedance.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [Ke,Fe,Re,Ve] = impedance(k) 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | % 2D Convected Helmholtz Equation 20 | % Notation: exp(-i \omega t) 21 | % Boundary condition: impedance 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % Linear boundary element associated to the T3 element 24 | % 2 nodes 25 | % 2 DOFs: p1, p2 26 | % Data in ELEMENT(:,k) : 27 | % 1,2: node numbers 28 | % 3,4: coordinates along the boundary 29 | % 5: number of this boundary 30 | % 6: number of the neighboring element 31 | % 7: number of the side in the neighboring element 32 | % Data in ELEMENT_DATA(:,k): 33 | % None 34 | % Data in NODE_DATA(:,k): 35 | % None 36 | % Data in BOUNDARY_DATA(:,k): 37 | % 1: impedance at node 1 38 | % 2: impedance at node 2 39 | 40 | if nargin==0 41 | % Return the properties of the element 42 | % Ke should contain: 43 | % the priority of the element 44 | % the number of nodes 45 | % the number of DOFs for node 1 46 | % the number of DOFs for node 2 47 | % ... 48 | % the number of internal DOFs of the element 49 | Ke = [5 2 1 1 0]; 50 | return 51 | end 52 | 53 | global omega 54 | global ELEMENT NODE NODE_DATA BOUNDARY_DATA 55 | 56 | RHO = NODE_DATA(1,ELEMENT(1,k)); 57 | C0 = NODE_DATA(2,ELEMENT(1,k)); 58 | 59 | % Boundary condition values (impedance Z) 60 | Z1 = BOUNDARY_DATA(1,k); 61 | Z2 = BOUNDARY_DATA(2,k); 62 | 63 | Ke = zeros(2,2); 64 | Fe = zeros(2,1); 65 | Re = zeros(2,2); 66 | Ve = zeros(2,1); 67 | 68 | N_GAUSS_POINT = 2; 69 | GAUSS_POINT = [1 -1]/sqrt(3); 70 | GAUSS_WEIGHT = [1 1]; 71 | 72 | x_point = NODE(1,ELEMENT(1:2,k))'; 73 | y_point = NODE(2,ELEMENT(1:2,k))'; 74 | 75 | for n=1:N_GAUSS_POINT 76 | % Coordinate of the Gauss point on the reference elements 77 | u = GAUSS_POINT(n); 78 | % Shape functions for the solution 79 | L = [1-u 1+u]/2; 80 | % Shape functions for the gradient of the solution 81 | Lu = [-1 1]/2; 82 | % Jacobian to the physical element 83 | Js = sqrt((Lu*x_point)^2+(Lu*y_point)^2); 84 | % Interpolate the impedance 85 | Z = L*[Z1;Z2]; 86 | % Add contribution to the element matrix 87 | Ke = Ke + GAUSS_WEIGHT(n)*( -1i*omega*RHO*C0^2/Z*(L'*L) )*Js; 88 | end 89 | -------------------------------------------------------------------------------- /Core/convert_T3_T6.m: -------------------------------------------------------------------------------- 1 | function [node,edge,element] = convert_T3_T6(node,edge,element,geom) 2 | 3 | side = edge; 4 | elem = element; 5 | 6 | segment = [elem(1:2,:) elem(2:3,:) [elem(3,:);elem(1,:)]]; 7 | seg_elem = [(1:size(elem,2)) (1:size(elem,2)) (1:size(elem,2))]; 8 | temp = sparse(segment(1,:),segment(2,:),seg_elem); 9 | [ii,jj,ss] = find(temp .* ((temp~=0).*(temp.'~=0))); 10 | edge = [ii' ; jj' ; ss']; 11 | [~,~,ss] = find(temp.' .* ((temp~=0).*(temp.'~=0))); 12 | edge = [edge ; ss']; 13 | edge = edge(:,edge(3,:)>edge(4,:)); 14 | [ii,jj,ss] = find(temp .* not((temp~=0).*(temp.'~=0))); 15 | edge = [edge [ii' ; jj' ; ss' ; 0*ss' ]]; 16 | 17 | X = node(1,:); 18 | Y = node(2,:); 19 | 20 | new_node = [ X(edge(1,:))+X(edge(2,:)) ; Y(edge(1,:))+Y(edge(2,:)) ]/2; 21 | n_new_node = size(new_node,2); 22 | n_node = size(node,2); 23 | node = [ node new_node ]; 24 | 25 | % Add the new nodes to the definitions of the elements 26 | element = zeros(6,size(elem,2)); 27 | element([1 3 5],:) = elem(1:3,:); 28 | for n=1:n_new_node 29 | n1 = edge(1,n); 30 | n2 = edge(2,n); 31 | 32 | e = edge(3,n); 33 | if ((elem(1,e)==n1)&&(elem(2,e)==n2))||((elem(1,e)==n2)&&(elem(2,e)==n1)) 34 | element(2,e) = n + n_node; 35 | end 36 | if ((elem(2,e)==n1)&&(elem(3,e)==n2))||((elem(2,e)==n2)&&(elem(3,e)==n1)) 37 | element(4,e) = n + n_node; 38 | end 39 | if ((elem(3,e)==n1)&&(elem(1,e)==n2))||((elem(3,e)==n2)&&(elem(1,e)==n1)) 40 | element(6,e) = n + n_node; 41 | end 42 | 43 | e = edge(4,n); 44 | if e~=0 45 | if ((elem(1,e)==n1)&&(elem(2,e)==n2))||((elem(1,e)==n2)&&(elem(2,e)==n1)) 46 | element(2,e) = n + n_node; 47 | end 48 | if ((elem(2,e)==n1)&&(elem(3,e)==n2))||((elem(2,e)==n2)&&(elem(3,e)==n1)) 49 | element(4,e) = n + n_node; 50 | end 51 | if ((elem(3,e)==n1)&&(elem(1,e)==n2))||((elem(3,e)==n2)&&(elem(1,e)==n1)) 52 | element(6,e) = n + n_node; 53 | end 54 | end 55 | end 56 | element = [ element ; elem(end,:) ]; 57 | 58 | ns = find(edge(4,:)==0); 59 | edge = edge(1:4,ns); 60 | side = [ side ; zeros(2,size(side,2)) ]; 61 | side(end-2,:) = side(5,:); 62 | side(8:9,:) = side(3:4,:); 63 | for n=1:length(ns) 64 | n1 = edge(1,n); 65 | n2 = edge(2,n); 66 | 67 | for m=1:size(side,2) 68 | if ((side(1,m)==n1)&&(side(2,m)==n2))||((side(1,m)==n2)&&(side(2,m)==n1)) 69 | side(4,m) = ns(n) + n_node; 70 | side(5,m) = edge(3,n); 71 | end 72 | end 73 | end 74 | edge = side([1 4 2 3 5 7 8 9],:); 75 | 76 | % If provided use the geometry to move the nodes on the boundary exactly on 77 | % the surface. 78 | if nargin==4 79 | for n=1:size(edge,2) 80 | nn = edge(2,n); 81 | [x,y] = feval(geom, edge(6,n), mean(side(8:9,n)) ); 82 | node(1,nn) = x; 83 | node(2,nn) = y; 84 | end 85 | end 86 | 87 | % Node renumbering to reduce the bandwidth 88 | [p,inv_p] = reorder_node(element(1:6,:),6); 89 | node = node(:,p); 90 | element(1:6,:) = inv_p(element(1:6,:)); 91 | temp = edge(1:3,:); 92 | edge(1:3,:) = inv_p(temp); 93 | -------------------------------------------------------------------------------- /Core/ADD_BORDER_DOFS.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function ADD_BORDER_DOFS(nd, border_list, group_list) 18 | % Modify the degrees of freedom of a boundary element to include the 19 | % degrees of freedom of the adjacent domain element. 20 | % nd: domain number 21 | % border_list: list of border numbers that should be modified 22 | % group_list: list of group numbers for the domain elements to consider 23 | 24 | global ELEMENT N_NODE_ELEMENT 25 | global N_DOF_ELEMENT DOF_ELEMENT 26 | 27 | DOF_ELEMENT = sparse(DOF_ELEMENT); 28 | 29 | elem_list = GET_ELEMENT_LIST(nd,1,border_list); 30 | 31 | if nargin==3 32 | dom_list = GET_ELEMENT_LIST(nd,0,group_list); 33 | else 34 | dom_list = GET_ELEMENT_LIST(nd,0); 35 | end 36 | 37 | for n=1:length(elem_list) 38 | table = zeros(1,length(dom_list)); 39 | for m=1:N_NODE_ELEMENT(elem_list(n)) 40 | table = table + sum(ELEMENT(:,dom_list)==ELEMENT(m,elem_list(n)),1); 41 | end 42 | % Adjacent element number 43 | num = find(table==N_NODE_ELEMENT(elem_list(n))); 44 | % Problem detection 45 | if length(num)~=1 46 | error('A boundary element does not have a neighbour of has multiple ones !'); 47 | end 48 | % Loop over the dofs of the adjacent element 49 | for m=1:N_DOF_ELEMENT(dom_list(num)) 50 | % If the dof is already in the list, do not add it 51 | if ~any(DOF_ELEMENT(1:N_DOF_ELEMENT(elem_list(n)),elem_list(n))==DOF_ELEMENT(m,dom_list(num))) 52 | N_DOF_ELEMENT(elem_list(n)) = N_DOF_ELEMENT(elem_list(n)) + 1; 53 | DOF_ELEMENT(N_DOF_ELEMENT(elem_list(n)),elem_list(n)) = DOF_ELEMENT(m,dom_list(num)); 54 | end 55 | end 56 | % Loop over the nodes of the neighbouring element 57 | k = N_NODE_ELEMENT(elem_list(n)); 58 | for m=1:N_NODE_ELEMENT(dom_list(num)) 59 | % If the node is already in the list, do not add it 60 | if ~any(ELEMENT(1:k,elem_list(n))==ELEMENT(m,dom_list(num))) 61 | k = k+1; 62 | ELEMENT(k,elem_list(n)) = ELEMENT(m,dom_list(num)); 63 | end 64 | N_NODE_ELEMENT(elem_list(n)) = k; 65 | ELEMENT(k+1,elem_list(n)) = dom_list(num); 66 | end 67 | end 68 | 69 | % Back to standard coding 70 | DOF_ELEMENT = full(DOF_ELEMENT); 71 | 72 | % Commentaires 73 | % This function was tested for the T3, L2, L3 and T4 elements 74 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/Q4/element.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | function [Ke,Fe,Re,Ve] = element(k) 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | % 2D Convected Helmholtz Equation 19 | % Notation: exp(-i \omega t) 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | % Linear triangular element 22 | % 2 nodes 23 | % 3 DOFs: p1, p2 and p3 24 | % Data in ELEMENT_DATA(:,k): 25 | % None 26 | % Data in NODE_DATA(:,k): 27 | % rho0, c0, u0, v0, s 28 | 29 | if nargin==0 30 | % Return the properties of the element 31 | % Ke should contain: 32 | % the priority of the element 33 | % the number of nodes 34 | % the number of DOFs for node 1 35 | % the number of DOFs for node 2 36 | % ... 37 | % the number of internal DOFs of the element 38 | Ke = [1 4 1 1 1 1 0]; 39 | return 40 | end 41 | 42 | global omega 43 | global ELEMENT NODE NODE_DATA 44 | 45 | % Sound speed at the nodes 46 | C0 = NODE_DATA(2,ELEMENT(1,k)); 47 | % Mean flow velocity at the nodes 48 | U0 = NODE_DATA(3:4,ELEMENT(1:4,k)); 49 | % Source term at the nodes 50 | S = NODE_DATA(5,ELEMENT(1:4,k)); 51 | 52 | % Gauss points on the reference element 53 | N_GAUSS_POINT = 4; 54 | GAUSS_POINT = [1/sqrt(3) 1/sqrt(3) -1/sqrt(3) -1/sqrt(3); 1/sqrt(3) -1/sqrt(3) 1/sqrt(3) -1/sqrt(3) ]; 55 | GAUSS_WEIGHT = [1 1 1 1]; 56 | 57 | % Coordinates of the nodes 58 | x_node = NODE(1,ELEMENT(1:4,k)).'; 59 | y_node = NODE(2,ELEMENT(1:4,k)).'; 60 | 61 | % Initialise the output 62 | Ke = zeros(4,4); 63 | Fe = zeros(4,1); 64 | Re = zeros(4,4); 65 | Ve = zeros(4,1); 66 | 67 | % Integrate over the reference elements using the Gauss points 68 | for n=1:N_GAUSS_POINT 69 | % Coordinates of the Gauss point on the reference elements 70 | u = GAUSS_POINT(1,n); 71 | v = GAUSS_POINT(2,n); 72 | % Jacobian to the physical element 73 | J = [v-1 1-v 1+v -1-v ;u-1 -u-1 1+u 1-u]/4*[x_node y_node]; 74 | detJ = det(J); 75 | 76 | % Shape functions for the solution 77 | N = [(1-u)*(1-v) (1+u)*(1-v) (1+u)*(1+v) (1-u)*(1+v)]/4; 78 | % Shape functions for the gradient of the solution 79 | GRAD = J\[v-1 1-v 1+v -1-v ;u-1 -u-1 1+u 1-u]/4; 80 | % Material derivative 81 | D0pDt = -1i*omega*N + (N*U0')*GRAD; 82 | 83 | % Add the contribution to the element matrix 84 | Ke = Ke + GAUSS_WEIGHT(n)*( C0^2*(GRAD'*GRAD) - D0pDt'*D0pDt )*detJ; 85 | % Add the contribution to the right-hand side 86 | Fe = Fe + GAUSS_WEIGHT(n)*( N.'*N*S.' )*detJ; 87 | end 88 | 89 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/Q4/velocity.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [Ke,Fe,Re,Ve] = velocity(k) 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | % 2D Convected Helmholtz Equation 20 | % Notation: exp(-i \omega t) 21 | % Boundary condition: velocity 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % Linear boundary element associated to the T3 element 24 | % 2 nodes 25 | % 2 DOFs: p1, p2 26 | % Data in ELEMENT(:,k) : 27 | % 1,2: node numbers 28 | % 3,4: coordinates along the boundary 29 | % 5: number of this boundary 30 | % 6: number of the neighboring element 31 | % 7: number of the side in the neighboring element 32 | % Data in ELEMENT_DATA(:,k): 33 | % None 34 | % Data in NODE_DATA(:,k): 35 | % None 36 | % Data in BOUNDARY_DATA(:,k): 37 | % 1: impedance at node 1 38 | % 2: impedance at node 2 39 | 40 | if nargin==0 41 | % Return the properties of the element 42 | % Ke should contain: 43 | % the priority of the element 44 | % the number of nodes 45 | % the number of DOFs for node 1 46 | % the number of DOFs for node 2 47 | % ... 48 | % the number of internal DOFs of the element 49 | Ke = [5 2 1 1 0]; 50 | return 51 | end 52 | 53 | global omega 54 | global ELEMENT NODE NODE_DATA BOUNDARY_DATA 55 | 56 | RHO = NODE_DATA(1,ELEMENT(1,k)); 57 | C0 = NODE_DATA(2,ELEMENT(1,k)); 58 | 59 | % Boundary condition values (velocity at nodes) 60 | Vx1 = BOUNDARY_DATA(1,k); 61 | Vy1 = BOUNDARY_DATA(2,k); 62 | Vx2 = BOUNDARY_DATA(3,k); 63 | Vy2 = BOUNDARY_DATA(4,k); 64 | 65 | Ke = zeros(2,2); 66 | Fe = zeros(2,1); 67 | Re = zeros(2,2); 68 | Ve = zeros(2,1); 69 | 70 | N_GAUSS_POINT = 2; 71 | GAUSS_POINT = [1 -1]/sqrt(3); 72 | GAUSS_WEIGHT = [1 1]; 73 | 74 | x_point = NODE(1,ELEMENT(1:2,k))'; 75 | y_point = NODE(2,ELEMENT(1:2,k))'; 76 | 77 | % Compute the normal 78 | nox = [-1 1]*y_point; 79 | noy = [1 -1]*x_point; 80 | no = [nox noy]/norm([nox noy]); 81 | 82 | for n=1:N_GAUSS_POINT 83 | % Coordinate of the Gauss point on the reference elements 84 | u = GAUSS_POINT(n); 85 | % Shape functions for the solution 86 | L = [1-u 1+u]/2; 87 | % Shape functions for the gradient of the solution 88 | Lu = [-1 1]/2; 89 | % Jacobian to the physical element 90 | Js = sqrt((Lu*x_point)^2+(Lu*y_point)^2); 91 | % Interpolate the velocity 92 | Vx = L*[Vx1;Vx2]; 93 | Vy = L*[Vy1;Vy2]; 94 | % Pressure normal gradient 95 | dPdn = -1i*omega*RHO*(Vx*no(1)+Vy*no(2)); 96 | % Add contribution to the element rhs 97 | Fe = Fe + GAUSS_WEIGHT(n)*( L.'*dPdn )*Js; 98 | end 99 | -------------------------------------------------------------------------------- /Examples/Helmholtz_2D_BEM/DiffractionByPlaneWave/mainloop.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | % To find the solver 17 | addpath('../../../../Code_FEM/Core'); 18 | MANAGE_PATH 19 | 20 | global omega typegeo type Order 21 | global alpha beta % Burton Miller formulatio 22 | global N_GAUSS_POINT GAUSS_POINT GAUSS_WEIGHT 23 | global SHAPEFUNC DSHAPEFUNC 24 | 25 | % Diffraction of a circle by an incident Plane Wave 26 | 27 | %%%%%%%%%% Plane wave Excitation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | 29 | % Type of geometry 30 | typegeo = 'circle'; 31 | Perimeter = 2*pi; 32 | % Plane wave amplitude 33 | Ainc = 1; 34 | % Frequency 35 | KA = 0.1:0.01:5; 36 | ERROR = zeros(1,length(KA)); 37 | % 38 | indka = 0; 39 | for ka = KA 40 | indka = indka + 1; 41 | omega = ka*340; 42 | % Interpolation order 43 | Order = 2; 44 | % Fixed Number of BEM elements 45 | %Nelement = 20; 46 | % Or based on a dof density 47 | ndof = 6; 48 | Nelement = ceil(ndof*Perimeter*(ka/(2*pi))/Order); 49 | % Number of Gauss Points per wavelength 50 | NGPWL = 10; 51 | % Burton and Miller 52 | if strcmp(type,'open') 53 | alpha = 1; beta = 0; 54 | else 55 | alpha= 1i/ka; beta = 1; 56 | end 57 | % Mesh creation 58 | INIT_GEOMETRY 59 | [N_DIM,N_NODE,NODE,N_ELEMENT,N_NODE_ELEMENT,ELEMENT,N_DOMAIN... 60 | ,ELEMENT_DOMAIN,NODE_DOMAIN,ELEMENT_ID,NODE_ID] = feval('geobem',Nelement,Order); 61 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 62 | % Compute the element length 63 | LENGTH_ELEMENT = ElementLength(Order); 64 | ndofpwl = (N_NODE)/((sum(LENGTH_ELEMENT))/(2*pi/ka)); 65 | % Precompute the shape functions at the Gauss points 66 | N_GAUSS_POINT = max(max(ceil(LENGTH_ELEMENT*ka/(2*pi)*NGPWL),4)); 67 | [GAUSS_POINT,GAUSS_WEIGHT] = gauleg(-1,1,N_GAUSS_POINT); 68 | SHAPEFUNC = zeros(Order+1,N_GAUSS_POINT); 69 | DSHAPEFUNC = zeros(Order+1,N_GAUSS_POINT); 70 | for n=1:N_GAUSS_POINT 71 | [Nu,dNu]=shape_function(GAUSS_POINT(n),Order); 72 | SHAPEFUNC(:,n)=Nu; 73 | DSHAPEFUNC(:,n)=dNu; 74 | end 75 | fprintf('\n Numerical data: \n ka = %i, %1.2f dof per wavelength, Order of interp. = %i \n \n',ka,ndofpwl,Order); 76 | 77 | BUILD_MODEL 78 | BUILD_DOF 79 | BUILD_SYSTEM 80 | SOLVE_SYSTEM 81 | 82 | [Uanal] = CirclePlanewave_AnalyticalSolution(NODE,1); 83 | ErL2 = L2Error(U,Uanal); 84 | fprintf('L2 error: %g pc \n', ErL2); 85 | 86 | ERROR(indka) = ErL2; 87 | % plot the result 88 | %PlotResults 89 | end 90 | hold all; 91 | plot(KA,ERROR); -------------------------------------------------------------------------------- /Library/Helmholtz_2D/T3/element.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [Ke,Fe,Re,Ve] = element(k) 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | % 2D Convected Helmholtz Equation 20 | % Notation: exp(-i \omega t) 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | % Linear triangular element 23 | % 2 nodes 24 | % 3 DOFs: p1, p2 and p3 25 | % Data in ELEMENT_DATA(:,k): 26 | % None 27 | % Data in NODE_DATA(:,k): 28 | % rho0, c0, u0, v0, s 29 | 30 | if nargin==0 31 | % Return the properties of the element 32 | % Ke should contain: 33 | % the priority of the element 34 | % the number of nodes 35 | % the number of DOFs for node 1 36 | % the number of DOFs for node 2 37 | % ... 38 | % the number of internal DOFs of the element 39 | Ke = [1 3 1 1 1 0]; 40 | return 41 | end 42 | 43 | global omega 44 | global ELEMENT NODE NODE_DATA 45 | 46 | % Sound speed at the nodes 47 | C0 = NODE_DATA(2,ELEMENT(1,k)); 48 | % Mean flow velocity at the nodes 49 | U0 = NODE_DATA(3:4,ELEMENT(1:3,k)); 50 | % Source term at the nodes 51 | S = NODE_DATA(5,ELEMENT(1:3,k)); 52 | 53 | % Gauss points on the reference element 54 | N_GAUSS_POINT = 4; 55 | GAUSS_POINT = [1/3 1/5 3/5 1/5; 1/3 1/5 1/5 3/5]; 56 | GAUSS_WEIGHT = [-27/96 25/96 25/96 25/96]; 57 | 58 | % Coordinates of the nodes 59 | x_node = NODE(1,ELEMENT(1:3,k))'; 60 | y_node = NODE(2,ELEMENT(1:3,k))'; 61 | 62 | % Initialise the output 63 | Ke = zeros(3,3); 64 | Fe = zeros(3,1); 65 | Re = zeros(3,3); 66 | Ve = zeros(3,1); 67 | 68 | % Integrate over the reference elements using the Gauss points 69 | for n=1:N_GAUSS_POINT 70 | % Coordinates of the Gauss point on the reference elements 71 | u = GAUSS_POINT(1,n); 72 | v = GAUSS_POINT(2,n); 73 | % Jacobian to the physical element 74 | J = [-1 1 0;-1 0 1]*[x_node y_node]; 75 | detJ = det(J); 76 | 77 | %%%%%%%%%%%%%%%% 78 | if detJ <= 0 79 | error('Error in element.m: non-positive Jacobian'); 80 | end 81 | %%%%%%%%%%%%%%%%% 82 | 83 | % Shape functions for the solution 84 | N = [1-u-v u v]; 85 | % Shape functions for the gradient of the solution 86 | GRAD = J\[-1 1 0;-1 0 1]; 87 | % Material derivative 88 | D0pDt = -1i*omega*N + (N*U0')*GRAD; 89 | 90 | % Add the contribution to the element matrix 91 | Ke = Ke + GAUSS_WEIGHT(n)*( C0^2*(GRAD'*GRAD) - D0pDt'*D0pDt )*detJ; 92 | % Add the contribution to the right-hand side 93 | Fe = Fe + GAUSS_WEIGHT(n)*( N.'*N*S.' )*detJ; 94 | end 95 | -------------------------------------------------------------------------------- /Library/Potential_Flow_3D/T4/mach.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = mach(k) 2 | 3 | if nargin==0 4 | Ke = [4 3 1 1 1 0]; 5 | return 6 | end 7 | 8 | global U 9 | global ELEMENT NODE DOF_ELEMENT 10 | global BOUNDARY_DATA 11 | global Flow 12 | 13 | Ke = zeros(4); 14 | Fe = zeros(4,1); 15 | Re = zeros(4); 16 | Ve = zeros(4,1); 17 | 18 | 19 | % Integration points on triangle with vertex (0,0), (0,1) and (1,0) 20 | N_GAUSS_POINT = 3; 21 | GAUSS_POINT = [1/2 0 1/2 ; 1/2 1/2 0]; 22 | GAUSS_WEIGHT = [1/6 1/6 1/6]; 23 | % 24 | % Node coordinates (tetra4) 25 | x_node = NODE(1,ELEMENT(1:4,k)).'; 26 | y_node = NODE(2,ELEMENT(1:4,k)).'; 27 | z_node = NODE(3,ELEMENT(1:4,k)).'; 28 | 29 | % Node coordinates (tria3) 30 | x_point = NODE(1,ELEMENT(1:3,k)).'; 31 | y_point = NODE(2,ELEMENT(1:3,k)).'; 32 | z_point = NODE(3,ELEMENT(1:3,k)).'; 33 | 34 | % Geometry for integration (tria3) 35 | tu = [[-1 1 0]*x_point; [-1 1 0]*y_point; [-1 1 0]*z_point]; 36 | tv = [[-1 0 1]*x_point; [-1 0 1]*y_point; [-1 0 1]*z_point]; 37 | tw = [tu(2)*tv(3)-tu(3)*tv(2) ; tu(3)*tv(1)-tu(1)*tv(3) ; tu(1)*tv(2)-tu(2)*tv(1)]; 38 | Js = norm(tw); 39 | no = tw/norm(tw); 40 | 41 | Barycenter = [mean(NODE(1,ELEMENT(1:3,k))),mean(NODE(2,ELEMENT(1:3,k))),mean(NODE(3,ELEMENT(1:3,k)))]; 42 | % % 43 | % figure(1); 44 | % hold on; 45 | % quiver3(Barycenter(1),Barycenter(2),Barycenter(3),no(1),no(2),no(3)); 46 | % axis equal; 47 | 48 | 49 | % Current solution 50 | phi = U(DOF_ELEMENT(1:4,k)); 51 | 52 | % Imposed MACH NUMBER 53 | Mnodes = BOUNDARY_DATA(1:3,k); 54 | 55 | for n=1:N_GAUSS_POINT 56 | 57 | % Use the neighboring T4 element to calculate the velocity 58 | u = GAUSS_POINT(1,n); 59 | v = GAUSS_POINT(2,n); 60 | w = 0; 61 | % 62 | N = [(1-u-v-w) u v w]; 63 | X_tetra = N*NODE(1:3,ELEMENT(1:4,k)).'; 64 | % 65 | J = [-1 1 0 0 ; -1 0 1 0; -1 0 0 1]*[x_node y_node z_node]; 66 | GRAD = J\[-1 1 0 0 ; -1 0 1 0; -1 0 0 1]; 67 | % 68 | dphi = (GRAD*phi).'; 69 | v2 = dphi(1)^2 + dphi(2)^2 + dphi(3)^2 ; 70 | rho = Flow.rho_inf*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 )^(1/(Flow.gamma-1)); 71 | c2 = Flow.c_inf^2*( 1 + (Flow.gamma-1)/2*(Flow.v_inf^2-v2)/Flow.c_inf^2 ); 72 | if v2>c2 73 | error('The flow is supersonic: the calculation cannot proceed (c=%f, v=%f).', sqrt(c2), sqrt(v2)); 74 | end 75 | c = sqrt(c2); 76 | 77 | % T3 shape functions 78 | u = GAUSS_POINT(1,n); 79 | v = GAUSS_POINT(2,n); 80 | % 81 | L = [1-u-v u v]; 82 | X_tria = L*NODE(1:3,ELEMENT(1:3,k)).'; 83 | if norm(X_tetra-X_tria)>100*eps 84 | error('Problem in velocity!') 85 | else 86 | %plot3(X_tria(1),X_tria(2),X_tria(3),'o') 87 | end 88 | 89 | % Gradients of the current solution in the normal direction 90 | dphi_n = dphi(1)*no(1) + dphi(2)*no(2) + dphi(3)*no(3); 91 | 92 | % normal gradient 93 | Gn = GRAD(1,:)*no(1) + GRAD(2,:)*no(2) + GRAD(3,:)*no(3); 94 | 95 | % local prescribed velocity 96 | M = L*Mnodes; 97 | 98 | Ke(1:4,1:4) = Ke(1:4,1:4) + GAUSS_WEIGHT(n)*( rho*M*N.'*( dphi*GRAD - dphi_n*Gn )/c )*Js; 99 | Fe(1:4) = Fe(1:4) + GAUSS_WEIGHT(n)*( -rho*N'*M*c + rho*N.'*M*dphi_n*(M-dphi_n/c) )*Js; 100 | end 101 | 102 | end 103 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/T3/element_MassAndStiffness.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [Ke,Fe,Me,Ve] = element_MassAndStiffness(k) 18 | % Store the stiffness and mass matrices respectively in Ke, Me 19 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20 | % 2D Convected Helmholtz Equation 21 | % Notation: exp(-i \omega t) 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % Linear triangular element 24 | % 2 nodes 25 | % 3 DOFs: p1, p2 and p3 26 | % Data in ELEMENT_DATA(:,k): 27 | % None 28 | % Data in NODE_DATA(:,k): 29 | % rho0, c0, u0, v0, s 30 | 31 | if nargin==0 32 | % Return the properties of the element 33 | % Ke should contain: 34 | % the priority of the element 35 | % the number of nodes 36 | % the number of DOFs for node 1 37 | % the number of DOFs for node 2 38 | % ... 39 | % the number of internal DOFs of the element 40 | Ke = [1 3 1 1 1 0]; 41 | return 42 | end 43 | 44 | global omega 45 | global ELEMENT NODE NODE_DATA 46 | 47 | % Sound speed at the nodes 48 | C0 = NODE_DATA(2,ELEMENT(1,k)); 49 | % Mean flow velocity at the nodes 50 | U0 = NODE_DATA(3:4,ELEMENT(1:3,k)); 51 | % Source term at the nodes 52 | S = NODE_DATA(5,ELEMENT(1:3,k)); 53 | 54 | % Gauss points on the reference element 55 | N_GAUSS_POINT = 4; 56 | GAUSS_POINT = [1/3 1/5 3/5 1/5; 1/3 1/5 1/5 3/5]; 57 | GAUSS_WEIGHT = [-27/96 25/96 25/96 25/96]; 58 | 59 | % Coordinates of the nodes 60 | x_node = NODE(1,ELEMENT(1:3,k))'; 61 | y_node = NODE(2,ELEMENT(1:3,k))'; 62 | 63 | % Initialise the output 64 | Ke = zeros(3,3); 65 | Fe = zeros(3,1); 66 | Me = zeros(3,3); 67 | Ve = zeros(3,1); 68 | 69 | % Integrate over the reference elements using the Gauss points 70 | for n=1:N_GAUSS_POINT 71 | % Coordinates of the Gauss point on the reference elements 72 | u = GAUSS_POINT(1,n); 73 | v = GAUSS_POINT(2,n); 74 | % Jacobian to the physical element 75 | J = [-1 1 0;-1 0 1]*[x_node y_node]; 76 | detJ = det(J); 77 | 78 | %%%%%%%%%%%%%%%% 79 | if detJ <= 0 80 | error('Error in element.m: non-positive Jacobian'); 81 | end 82 | %%%%%%%%%%%%%%%%% 83 | 84 | % Shape functions for the solution 85 | N = [1-u-v u v]; 86 | % Shape functions for the gradient of the solution 87 | GRAD = J\[-1 1 0;-1 0 1]; 88 | % Material derivative 89 | %D0pDt = -1i*omega*N + (N*U0')*GRAD; 90 | 91 | % Add the contribution to the element matrix 92 | Ke = Ke + GAUSS_WEIGHT(n)*( GRAD'*GRAD )*detJ; 93 | Me = Me + GAUSS_WEIGHT(n)*( N'*N )*detJ; 94 | % Add the contribution to the right-hand side 95 | %Fe = Fe + GAUSS_WEIGHT(n)*( N.'*N*S.' )*detJ; 96 | end 97 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D/T3/velocity.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function [Ke,Fe,Re,Ve] = velocity(k) 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | % 2D Convected Helmholtz Equation 20 | % Notation: exp(+i \omega t) 21 | % Boundary condition: velocity 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % Linear boundary element associated to the T3 element 24 | % 2 nodes 25 | % 2 DOFs: p1, p2 26 | % Data in ELEMENT(:,k) : 27 | % 1,2: node numbers 28 | % 3,4: coordinates along the boundary 29 | % 5: number of this boundary 30 | % 6: number of the neighboring element 31 | % 7: number of the side in the neighboring element 32 | % Data in ELEMENT_DATA(:,k): 33 | % None 34 | % Data in NODE_DATA(:,k): 35 | % None 36 | % Data in BOUNDARY_DATA(:,k): 37 | % 1: impedance at node 1 38 | % 2: impedance at node 2 39 | 40 | if nargin==0 41 | % Return the properties of the element 42 | % Ke should contain: 43 | % the priority of the element 44 | % the number of nodes 45 | % the number of DOFs for node 1 46 | % the number of DOFs for node 2 47 | % ... 48 | % the number of internal DOFs of the element 49 | Ke = [5 2 1 1 0]; 50 | return 51 | end 52 | 53 | global omega 54 | global ELEMENT NODE NODE_DATA BOUNDARY_DATA 55 | 56 | RHO = NODE_DATA(1,ELEMENT(1,k)); 57 | C0 = NODE_DATA(2,ELEMENT(1,k)); 58 | 59 | % Boundary condition values (velocity at nodes) 60 | Vx1 = BOUNDARY_DATA(1,k); 61 | Vy1 = BOUNDARY_DATA(2,k); 62 | Vx2 = BOUNDARY_DATA(3,k); 63 | Vy2 = BOUNDARY_DATA(4,k); 64 | 65 | Ke = zeros(2,2); 66 | Fe = zeros(2,1); 67 | Re = zeros(2,2); 68 | Ve = zeros(2,1); 69 | 70 | N_GAUSS_POINT = 2; 71 | GAUSS_POINT = [1 -1]/sqrt(3); 72 | GAUSS_WEIGHT = [1 1]; 73 | 74 | x_point = NODE(1,ELEMENT(1:2,k))'; 75 | y_point = NODE(2,ELEMENT(1:2,k))'; 76 | 77 | % Compute the normal 78 | nox = [-1 1]*y_point; 79 | noy = [1 -1]*x_point; 80 | no = [nox noy]/norm([nox noy]); 81 | 82 | for n=1:N_GAUSS_POINT 83 | % Coordinate of the Gauss point on the reference elements 84 | u = GAUSS_POINT(n); 85 | % Shape functions for the solution 86 | L = [1-u 1+u]/2; 87 | % Shape functions for the gradient of the solution 88 | Lu = [-1 1]/2; 89 | % Jacobian to the physical element 90 | Js = sqrt((Lu*x_point)^2+(Lu*y_point)^2); 91 | % Interpolate the velocity 92 | Vx = L*[Vx1;Vx2]; 93 | Vy = L*[Vy1;Vy2]; 94 | % Pressure normal gradient 95 | dPdn = -1i*omega*RHO*(Vx*no(1)+Vy*no(2)); 96 | % Add contribution to the element rhs 97 | Fe = Fe + GAUSS_WEIGHT(n)*( L.'*dPdn )*Js; 98 | end 99 | 100 | -------------------------------------------------------------------------------- /Examples/Potential_Flow_2D/Contraction/main.m: -------------------------------------------------------------------------------- 1 | % Solve the steady, potential, compressible flow through a 2D duct 2 | 3 | % Add the Core directory to the path 4 | addpath(fullfile('..','..','..','..','Code_FEM','Core')); 5 | 6 | global LIBRARY_PATH %#ok 7 | MANAGE_PATH 8 | 9 | % Properties of the flow at infinity 10 | global Flow 11 | Flow.gamma = 1.4; 12 | Flow.rho_inf = 1.2; 13 | Flow.c_inf = 340; 14 | Flow.outlet_velocity = Flow.c_inf*0.33; 15 | Flow.v_inf = Flow.outlet_velocity; 16 | 17 | % Create a T3 mesh 18 | % [node, edge, element] = initmesh('geometry', 'Jiggle', 'mean', 'JiggleIter', 20, 'Hmax', 0.1); 19 | % or load an example of mesh 20 | load mesh_example 21 | 22 | % Convert the mesh to T6 elements 23 | [node, edge, element] = convert_T3_T6(node, edge, element, @geometry); 24 | 25 | % Plot the mesh 26 | figure; 27 | PLOT_FEM(node(1:2, :), element(1:6, :)); 28 | axis equal; axis tight; box on; 29 | 30 | INIT_GEOMETRY 31 | 32 | ADD_DOMAIN(node, edge, element); 33 | 34 | BUILD_MODEL 35 | BUILD_DOF 36 | 37 | % The boundary elements need to have access to the T6 elements 38 | ADD_BORDER_DOFS(1, 1:8); 39 | 40 | 41 | %% Calculate the incompressible flow 42 | 43 | % The current solution will be used by the element functions 44 | global U 45 | 46 | % Initial solution 47 | U = zeros(N_DOF,1); 48 | 49 | % Instead of using a separate model for the incompressible flow the trick 50 | % is to set the reference sound speed to infinity. All the terms associated 51 | % with compressibility will naturally drop from the formulation. 52 | c_inf_backup = Flow.c_inf; 53 | Flow.c_inf = inf; 54 | 55 | % Build and solve the linear system 56 | BUILD_SYSTEM; 57 | SOLVE_SYSTEM; 58 | 59 | % Restore the actual value of the reference sound speed 60 | Flow.c_inf = c_inf_backup; 61 | clear c_inf_backup 62 | 63 | 64 | %% Solving non-linear problem for the compressible flow 65 | 66 | % Maximum number of iterations for each step 67 | N_MAX_ITER = 100; 68 | % Convergence criteria for the iterations 69 | ERROR = 1.0e-12; 70 | 71 | % We use a basic Newton-Raphson method to solve the non-linear equations 72 | for iter=1:N_MAX_ITER 73 | fprintf('\nITERATION %i\n', iter); 74 | % Build and solve the linear system for this iteration 75 | BUILD_SYSTEM; 76 | Uold = U; 77 | SOLVE_SYSTEM; 78 | % The norm of the delta 79 | e = norm(U); 80 | % Update the solution 81 | U = Uold+U; 82 | % Relative change in solution 83 | e = e/norm(U); 84 | % Test for convergence 85 | fprintf('ITERATION ERROR: %e\n',e); 86 | if e < ERROR 87 | break 88 | end 89 | end 90 | 91 | % Plot the velocity potential 92 | figure 93 | PLOT_FEM(node(1:2,:), element(1:6,:), full(U)) 94 | axis equal; axis tight; box on; 95 | colorbar; 96 | title('velocity potential'); 97 | 98 | 99 | %% Calculate the velocity and other flow properties 100 | get_flow; 101 | 102 | % Plot the properties of the flow 103 | figure 104 | PLOT_FEM(node(1:2,:), element(1:6,:), Vx) 105 | axis equal; axis tight; box on; 106 | colorbar; 107 | title('vx'); 108 | 109 | figure 110 | PLOT_FEM(node(1:2,:), element(1:6,:), Vy) 111 | axis equal; axis tight; box on; 112 | colorbar; 113 | title('vy'); 114 | 115 | figure 116 | PLOT_FEM(node(1:2,:), element(1:6,:), V./c) 117 | axis equal; axis tight; box on; 118 | colorbar; 119 | title('Mach number'); 120 | 121 | figure 122 | PLOT_FEM(node(1:2,:), element(1:6,:), rho) 123 | axis equal; axis tight; box on; 124 | colorbar; 125 | title('density'); 126 | 127 | figure 128 | PLOT_FEM(node(1:2,:), element(1:6,:), c) 129 | axis equal; axis tight; box on; 130 | colorbar; 131 | title('sound speed'); 132 | -------------------------------------------------------------------------------- /Examples/Potential_Flow_Axi/Contraction/main.m: -------------------------------------------------------------------------------- 1 | % Solve the steady, potential, compressible flow through an axi-symmetric duct 2 | 3 | % Add the Core directory to the path 4 | addpath(fullfile('..','..','..','..','Code_FEM','Core')); 5 | 6 | global LIBRARY_PATH %#ok 7 | MANAGE_PATH 8 | 9 | % Properties of the flow at infinity 10 | global Flow 11 | Flow.gamma = 1.4; 12 | Flow.rho_inf = 1.2; 13 | Flow.c_inf = 340; 14 | Flow.outlet_velocity = Flow.c_inf*0.25; 15 | Flow.v_inf = Flow.outlet_velocity; 16 | 17 | % Create a T3 mesh 18 | % [node, edge, element] = initmesh('geometry', 'Jiggle', 'mean', 'JiggleIter', 20, 'Hmax', 0.08); 19 | % or load an example of mesh 20 | load mesh_example 21 | 22 | % Convert the mesh to T6 elements 23 | [node, edge, element] = convert_T3_T6(node, edge, element, @geometry); 24 | 25 | % Plot the mesh 26 | figure; 27 | PLOT_FEM(node(1:2, :), element(1:6, :)); 28 | axis equal; axis tight; box on; 29 | 30 | INIT_GEOMETRY 31 | 32 | ADD_DOMAIN(node, edge, element); 33 | 34 | BUILD_MODEL 35 | BUILD_DOF 36 | 37 | % The boundary elements need to have access to the T6 elements 38 | ADD_BORDER_DOFS(1, 1:8); 39 | 40 | 41 | %% Calculate the incompressible flow 42 | 43 | % The current solution will be used by the element functions 44 | global U 45 | 46 | % Initial solution 47 | U = zeros(N_DOF,1); 48 | 49 | % Instead of using a separate model for the incompressible flow the trick 50 | % is to set the reference sound speed to infinity. All the terms associated 51 | % with compressibility will naturally drop from the formulation. 52 | c_inf_backup = Flow.c_inf; 53 | Flow.c_inf = inf; 54 | 55 | % Build and solve the linear system 56 | BUILD_SYSTEM; 57 | SOLVE_SYSTEM; 58 | 59 | % Restore the actual value of the reference sound speed 60 | Flow.c_inf = c_inf_backup; 61 | clear c_inf_backup 62 | 63 | 64 | %% Solving non-linear problem for the compressible flow 65 | 66 | % Maximum number of iterations for each step 67 | N_MAX_ITER = 100; 68 | % Convergence criteria for the iterations 69 | ERROR = 1.0e-12; 70 | 71 | % We use a basic Newton-Raphson method to solve the non-linear equations 72 | for iter=1:N_MAX_ITER 73 | fprintf('\nITERATION %i\n', iter); 74 | % Build and solve the linear system for this iteration 75 | BUILD_SYSTEM; 76 | Uold = U; 77 | SOLVE_SYSTEM; 78 | % The norm of the delta 79 | e = norm(U); 80 | % Update the solution 81 | U = Uold+U; 82 | % Relative change in solution 83 | e = e/norm(U); 84 | % Test for convergence 85 | fprintf('ITERATION ERROR: %e\n',e); 86 | if e < ERROR 87 | break 88 | end 89 | end 90 | 91 | % Plot the velocity potential 92 | figure 93 | PLOT_FEM(node(1:2,:), element(1:6,:), full(U)) 94 | axis equal; axis tight; box on; 95 | colorbar; 96 | title('velocity potential'); 97 | 98 | 99 | %% Calculate the velocity and other flow properties 100 | get_flow; 101 | 102 | % Plot the properties of the flow 103 | figure 104 | PLOT_FEM(node(1:2,:), element(1:6,:), Vx) 105 | axis equal; axis tight; box on; 106 | colorbar; 107 | title('vx'); 108 | 109 | figure 110 | PLOT_FEM(node(1:2,:), element(1:6,:), Vy) 111 | axis equal; axis tight; box on; 112 | colorbar; 113 | title('vy'); 114 | 115 | figure 116 | PLOT_FEM(node(1:2,:), element(1:6,:), V./c) 117 | axis equal; axis tight; box on; 118 | colorbar; 119 | title('Mach number'); 120 | 121 | figure 122 | PLOT_FEM(node(1:2,:), element(1:6,:), rho) 123 | axis equal; axis tight; box on; 124 | colorbar; 125 | title('density'); 126 | 127 | figure 128 | PLOT_FEM(node(1:2,:), element(1:6,:), c) 129 | axis equal; axis tight; box on; 130 | colorbar; 131 | title('sound speed'); 132 | -------------------------------------------------------------------------------- /Core/ADD_DOMAIN.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | function ADD_DOMAIN(node,edge,element) 18 | % Import a mesh generated by PDETOOL as an additional domain 19 | 20 | global N_DIM N_NODE NODE ELEMENT_ID 21 | global N_ELEMENT N_NODE_ELEMENT ELEMENT 22 | global N_DOMAIN ELEMENT_DOMAIN NODE_DOMAIN 23 | 24 | % If this is the first domain, the procedure is a bit different 25 | if N_DOMAIN == 0 26 | N_DIM = size(node,1); 27 | N_DOMAIN = 1; 28 | % Let's add the nodes 29 | NODE = node; 30 | % The number of domain elements 31 | n_element = size(element,2); 32 | % The number of boundary elements 33 | n_edge = size(edge,2); 34 | % For the domain elements 35 | % Define the number of nodes per element. 36 | % We assume that all the elements in this domain have the same number of 37 | % nodes per element 38 | N_NODE_ELEMENT = ones(1,n_element)*(size(element,1)-1); 39 | % Define the list of nodes for each element 40 | ELEMENT = element(1:end-1,:); 41 | % Define the description of each element 42 | ELEMENT_DOMAIN = [N_DOMAIN*ones(1,size(element,2));zeros(1,size(element,2));element(end,:);2*ones(1,size(element,2))]; 43 | % For the boundary elements 44 | % Add the number of nodes per element. 45 | N_NODE_ELEMENT = [N_NODE_ELEMENT ones(1,n_edge)*(size(edge,1)-5)]; 46 | % Add the list of nodes for each element 47 | ELEMENT = [ELEMENT [edge(1:end-5,:)+N_NODE;zeros(size(ELEMENT,1)-size(edge,1)+5,size(edge,2))]]; 48 | % Add the description of each element 49 | ELEMENT_DOMAIN = [ELEMENT_DOMAIN [N_DOMAIN*ones(1,size(edge,2));ones(1,size(edge,2));edge(end-2,:);ones(1,size(edge,2))]]; 50 | % Total number of elements 51 | N_ELEMENT = N_ELEMENT + n_element + n_edge; 52 | % Total number of nodes 53 | N_NODE = size(node,2); 54 | % The domain to which each node belongs 55 | NODE_DOMAIN = ones(1,N_NODE); 56 | else 57 | % In that case we are adding a domain 58 | N_DOMAIN = N_DOMAIN + 1; 59 | % Add the new nodes 60 | NODE = [NODE node]; 61 | % The number of domain elements 62 | n_element = size(element,2); 63 | % The number of boundary elements 64 | n_edge = size(edge,2); 65 | % The number of nodes 66 | n_node = size(node,2); 67 | % For the domain elements 68 | % Define the number of nodes per element. 69 | N_NODE_ELEMENT = [N_NODE_ELEMENT ones(1,n_element)*(size(element,1)-1)]; 70 | % Define the list of nodes for each element 71 | if size(ELEMENT,1)>=(size(element,1)-1) 72 | ELEMENT = [ELEMENT [element(1:end-1,:)+N_NODE;zeros(size(ELEMENT,1)-size(element,1)+1,size(element,2))]]; 73 | else 74 | ELEMENT = [[ELEMENT;zeros(size(element,1)-1-size(ELEMENT,1),size(ELEMENT,2))] element(1:end-1,:)+N_NODE]; 75 | end 76 | % Define the description of each element 77 | ELEMENT_DOMAIN = [ELEMENT_DOMAIN [N_DOMAIN*ones(1,size(element,2));zeros(1,size(element,2));element(end,:)]]; 78 | % For the boundary elements 79 | % Add the number of nodes per element. 80 | N_NODE_ELEMENT = [N_NODE_ELEMENT ones(1,n_edge)*(size(edge,1)-5)]; 81 | % Add the list of nodes for each element 82 | ELEMENT = [ELEMENT [edge(1:end-5,:)+N_NODE;zeros(size(ELEMENT,1)-size(edge,1)+5,size(edge,2))]]; 83 | % Add the description of each element 84 | ELEMENT_DOMAIN = [ELEMENT_DOMAIN [N_DOMAIN*ones(1,size(edge,2));ones(1,size(edge,2));edge(end-2,:)]]; 85 | % Total number of elements 86 | N_ELEMENT = N_ELEMENT+n_element+n_edge; 87 | % Total number of nodes 88 | N_NODE = N_NODE+n_node; 89 | % The domain to which each node belongs 90 | NODE_DOMAIN = [NODE_DOMAIN N_DOMAIN*ones(1,n_node)]; 91 | end 92 | 93 | ELEMENT_ID = 1:N_ELEMENT; 94 | -------------------------------------------------------------------------------- /Core/BUILD_MODEL.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | % Construct the data describing the physics of the problem 18 | 19 | global N_RHS 20 | global ELEMENT_NAME ELEMENT_LIST 21 | global ELEMENT_DATA NODE_DATA BOUNDARY_DATA 22 | global INTERFACE INTERFACE_NAME 23 | global DOMAIN_METHOD DOMAIN_PATH 24 | fprintf('BUILD_MODEL: '); 25 | 26 | if isempty(N_RHS) 27 | N_RHS = 1; 28 | end 29 | ELEMENT_NAME = []; 30 | ELEMENT_DATA = []; 31 | ELEMENT_LIST = zeros(1,N_ELEMENT); 32 | NODE_DATA = sparse(1000,N_NODE); 33 | BOUNDARY_DATA = sparse(1000,N_ELEMENT); 34 | DOMAIN_PATH = cell(2,N_DOMAIN); 35 | INTERFACE = cell(N_DOMAIN,N_DOMAIN); 36 | INTERFACE_NAME = cell(N_DOMAIN,N_DOMAIN); 37 | DOMAIN_METHOD = cell(N_DOMAIN,N_DOMAIN); 38 | max_elem = 0; 39 | max_node = 0; 40 | % Loop over all the domains 41 | for k=1:N_DOMAIN 42 | % Create a list of elements part of the current domain 43 | list = find(ELEMENT_DOMAIN(1,:)==k); 44 | % Call the 'domain' function to get the info about it 45 | temp = domain(k); 46 | % Store the problem name 47 | PROBLEM = temp{1}{1}; 48 | % Store the method to be used for this domain 49 | DOMAIN_METHOD{k,k} = temp{1}{2}; 50 | % Store the directories containing the element functions 51 | ZExist=0; 52 | for iPath = 1:length(LIBRARY_PATH) 53 | LocalPath = [LIBRARY_PATH{iPath} filesep PROBLEM filesep temp{1}{3} filesep]; 54 | DOMAIN_PATH{iPath,k} = LocalPath; 55 | if (exist(LocalPath,'dir')) 56 | ZExist=1; 57 | end 58 | end 59 | if (ZExist == 0) 60 | error('Elementary folder routine could not be accessed!') 61 | end 62 | % Loop over the elements of the domain 63 | for j=1:length(list) 64 | % If it is a domain element 65 | if ELEMENT_DOMAIN(2,list(j))==0 66 | if size(temp{1},2)==4 67 | % Store the name of the element function 68 | [number,ELEMENT_NAME] = ADD_TO_LIST(ELEMENT_NAME,temp{1}{4}); 69 | ELEMENT_LIST(list(j)) = number; 70 | else 71 | % Store the name of the element function 72 | [number,ELEMENT_NAME] = ADD_TO_LIST(ELEMENT_NAME,temp{1}{3+ELEMENT_DOMAIN(3,list(j))}); 73 | ELEMENT_LIST(list(j)) = number; 74 | end 75 | end 76 | % If it is a boundary element 77 | if ELEMENT_DOMAIN(2,list(j))==1 78 | % Call the 'boundary' function to get the description of the 79 | % boundary 80 | name = boundary(k,ELEMENT_DOMAIN(3,list(j))); 81 | [number,ELEMENT_NAME] = ADD_TO_LIST(ELEMENT_NAME,name); 82 | ELEMENT_LIST(list(j)) = number; 83 | name = []; 84 | for n=1:N_NODE_ELEMENT(list(j)) 85 | % Store the name of the element function 86 | name = [name;boundary(k,ELEMENT_DOMAIN(3,list(j)),NODE(:,ELEMENT(n,list(j)))).']; %#ok 87 | end 88 | % Store the data associated with this boundary condition 89 | BOUNDARY_DATA(1:length(name),list(j)) = name; %#ok 90 | max_elem = max(max_elem,length(name)); 91 | end 92 | end 93 | % If there is coupling between domains 94 | for j=2:size(temp,1) 95 | DOMAIN_METHOD{k,temp{j}{1}} = temp{j}{2}; 96 | INTERFACE_NAME{k,temp{j}{1}} = temp{j}{3}; 97 | INTERFACE{k,temp{j}{1}} = temp{j}{4}; 98 | end 99 | % Call the 'domain' function to get the data associated with the nodes 100 | list = find(NODE_DOMAIN==k); 101 | temp = domain(k,NODE(:,list)); 102 | NODE_DATA(1:size(temp,1),list) = temp; %#ok 103 | max_node = max(max_node,size(temp,1)); 104 | end 105 | 106 | NODE_DATA = full(NODE_DATA(1:max_node,:)); 107 | BOUNDARY_DATA = full(BOUNDARY_DATA(1:max_elem,:)); 108 | 109 | fprintf('%i domains, %i nodes, %i elements\n',N_DOMAIN,N_NODE,N_ELEMENT); 110 | 111 | % Remove temporary variables 112 | clear k j n temp list number name ii jj ss 113 | clear max_node max_elem 114 | clear public private -------------------------------------------------------------------------------- /Core/BUILD_DOF.m: -------------------------------------------------------------------------------- 1 | % This program is free software: you can redistribute it and/or modify 2 | % it under the terms of the GNU General Public License as published by 3 | % the Free Software Foundation, either version 3 of the License, or 4 | % (at your option) any later version. 5 | % 6 | % This program is distributed in the hope that it will be useful, 7 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | % GNU General Public License for more details. 10 | % 11 | % You should have received a copy of the GNU General Public License 12 | % along with this program. If not, see . 13 | % 14 | % Copyright (c) 2014 Code_FEM developers 15 | 16 | 17 | % Construct lists of degrees of freedom 18 | global N_DOF_ELEMENT N_IDOF_ELEMENT N_DOF 19 | global DOF_NODE N_DOF_NODE DOF_ELEMENT 20 | fprintf('BUILD_DOF: '); 21 | 22 | % N_IDOF_ELEMENT(i) : number of internal degrees of freedom for the ith 23 | % element 24 | N_IDOF_ELEMENT = zeros(1,N_ELEMENT); 25 | % N_DOF_ELEMENT(i) : number of degrees of freedom for the ith element 26 | N_DOF_ELEMENT = zeros(1,N_ELEMENT); 27 | % The level of priority of the elements 28 | priority = zeros(1,N_ELEMENT); 29 | % Go through each domain at a time 30 | for k=1:N_DOMAIN 31 | % Create a list of elements for this domain 32 | list = find(ELEMENT_DOMAIN(1,:)==k); 33 | % Get access to the element functions for this domain 34 | if (exist(DOMAIN_PATH{1,k},'dir')) 35 | addpath(DOMAIN_PATH{1,k}); 36 | end 37 | if (exist(DOMAIN_PATH{2,k},'dir')) 38 | addpath(DOMAIN_PATH{2,k}); 39 | end 40 | for j=1:length(list) 41 | % Call the element function 42 | temp = feval(char(ELEMENT_NAME(ELEMENT_LIST(list(j))))); 43 | % Check that the number of nodes given by the element function is 44 | % consistent with what is given in the geometry 45 | if N_NODE_ELEMENT(list(j))~=temp(2) 46 | error('Incompatibility between the element geometrical description and the element assembly function.'); 47 | end 48 | % Number of internal degrees of freedom 49 | N_IDOF_ELEMENT(list(j)) = temp(end); 50 | % Number of degrees of freedom 51 | N_DOF_ELEMENT(list(j)) = sum(temp(3:end)); 52 | % The level of priority of this element compared to the others 53 | priority(list(j)) = temp(1); 54 | end 55 | if (exist(DOMAIN_PATH{1,k},'dir')) 56 | rmpath(DOMAIN_PATH{1,k}); 57 | end 58 | if (exist(DOMAIN_PATH{2,k},'dir')) 59 | rmpath(DOMAIN_PATH{2,k}); 60 | end 61 | end 62 | 63 | % Associate degrees of freedom to nodes and elements 64 | % N_DOF_NODE(i) is the number of degrees of freedom for the ith node 65 | N_DOF_NODE = zeros(1,N_NODE); 66 | % N_DOF is the total number of degrees of freedom 67 | N_DOF = 0; 68 | % DOF_NODE(i,j) is the number of the ith degree of freedom of the jth node 69 | DOF_NODE = zeros(max(N_DOF_NODE),N_NODE); 70 | % DOF_ELEMENT(i,j) is the number of the ith degree of freedom of the jth 71 | % element 72 | DOF_ELEMENT = zeros(max(N_DOF_ELEMENT),N_ELEMENT); 73 | % Work each domain at a time 74 | for k=1:N_DOMAIN 75 | % Create a list of elements for this domain 76 | list = find(ELEMENT_DOMAIN(1,:)==k); 77 | % Create a list of nodes for this domain 78 | node_list = find(NODE_DOMAIN==k); 79 | % Get access to the element functions for this domain 80 | if (exist(DOMAIN_PATH{1,k},'dir')) 81 | addpath(DOMAIN_PATH{1,k}); 82 | end 83 | if (exist(DOMAIN_PATH{2,k},'dir')) 84 | addpath(DOMAIN_PATH{2,k}); 85 | end 86 | % Loop over all the elements of this domain 87 | for j=1:length(list) 88 | % Call element function to know the number of degrees of freedom 89 | temp = feval(char(ELEMENT_NAME(ELEMENT_LIST(list(j))))); 90 | % Store the number of degrees of freedom for the nodes 91 | N_DOF_NODE(ELEMENT(1:N_NODE_ELEMENT(list(j)),list(j))) = temp(3:end-1); 92 | end 93 | % Loop over the nodes of the domain 94 | for j=1:length(node_list) 95 | % Number the degrees of freedom and store these numbers 96 | DOF_NODE(1:N_DOF_NODE(node_list(j)),node_list(j)) = ( (N_DOF+1):(N_DOF+N_DOF_NODE(node_list(j))) )'; 97 | N_DOF = N_DOF+N_DOF_NODE(node_list(j)); 98 | end 99 | % Loop over all the elements of this domain 100 | for j=1:length(list) 101 | % Associate the degrees of freedom to the elements 102 | temp = DOF_NODE(:,ELEMENT(1:N_NODE_ELEMENT(list(j)),list(j))); 103 | temp = temp(:); 104 | DOF_ELEMENT(1:N_DOF_ELEMENT(list(j))-N_IDOF_ELEMENT(list(j)),list(j)) = temp(find(temp)); 105 | DOF_ELEMENT(N_DOF_ELEMENT(list(j))-N_IDOF_ELEMENT(list(j))+1:N_DOF_ELEMENT(list(j)),list(j)) = ( (N_DOF+1):(N_DOF+N_IDOF_ELEMENT(list(j))) )'; 106 | N_DOF = N_DOF + N_IDOF_ELEMENT(list(j)); 107 | end 108 | if (exist(DOMAIN_PATH{1,k},'dir')) 109 | rmpath(DOMAIN_PATH{1,k}); 110 | end 111 | if (exist(DOMAIN_PATH{2,k},'dir')) 112 | rmpath(DOMAIN_PATH{2,k}); 113 | end 114 | end 115 | fprintf('%i DOFs\n',N_DOF); 116 | 117 | % Remove temporary variables 118 | clear order temp priority k j list node_list 119 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D_BEM/L2/DBEM_Wall_Wall.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = DBEM_Wall_Wall(m,p) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % Helmholtz equation BEM formulation (direct BEM) 4 | % Isoparametric high-order element (Lagrange polynomial) 5 | % Interpolation depends on order 6 | % L2->1, L3->2, ... 7 | % Right hand side: Diffraction by a plane wave 8 | % Formulation: 9 | % 1/2*\int_Sx {\phi*(X) \phi(Y)} dSx 10 | % - \int_Sx \int_Sy {\phi*(X) \phi(Y) dG(X,Y)/dny} dSy dSx 11 | % = \int_Sx {\phi*(X) \phi_inc(X)} dSp 12 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 | 14 | global Order 15 | 16 | NrOfNodes = (Order+1); 17 | 18 | if nargin==0 19 | Ke = [1 NrOfNodes ones(1,NrOfNodes) 0]; 20 | return 21 | end 22 | 23 | global omega 24 | global ELEMENT NODE NODE_DATA 25 | global N_GAUSS_POINT GAUSS_POINT GAUSS_WEIGHT 26 | global SHAPEFUNC DSHAPEFUNC 27 | 28 | RHO = NODE_DATA(1,ELEMENT(1,m)); 29 | C0 = NODE_DATA(2,ELEMENT(1,m)); 30 | K = (omega/C0); 31 | 32 | Ke = zeros(NrOfNodes,NrOfNodes); 33 | Fe = zeros(NrOfNodes,1); 34 | Re = zeros(NrOfNodes,NrOfNodes); 35 | Ve = zeros(NrOfNodes,1); 36 | 37 | % Density quadrature factor (For the auto-influence computation) 38 | QuadAutoFactor = 1; 39 | 40 | x_nodem = NODE(1,ELEMENT(:,m))'; 41 | y_nodem = NODE(2,ELEMENT(:,m))'; 42 | 43 | %-------------------------------------------------------------------------- 44 | % Double integration (Calling function with a double argument) 45 | %-------------------------------------------------------------------------- 46 | if nargin ==2 47 | x_nodep = NODE(1,ELEMENT(:,p))'; 48 | y_nodep = NODE(2,ELEMENT(:,p))'; 49 | % Standard quadrature (elements do not coincide) 50 | if m~=p 51 | % integrating over M 52 | for mm=1:N_GAUSS_POINT 53 | u = GAUSS_POINT(mm); 54 | Nu = SHAPEFUNC(:,mm)'; 55 | dNu = DSHAPEFUNC(:,mm)'; 56 | Jm = [dNu*x_nodem dNu*y_nodem]; 57 | M = [Nu*x_nodem Nu*y_nodem]; 58 | % integrating over P 59 | for pp=1:N_GAUSS_POINT 60 | v = GAUSS_POINT(pp); 61 | Nv = SHAPEFUNC(:,pp)'; 62 | dNv = DSHAPEFUNC(:,pp)'; 63 | Jp = [dNv*x_nodep dNv*y_nodep]; 64 | P = [Nv*x_nodep Nv*y_nodep]; 65 | R = norm(P-M); 66 | %G = -i/4*besselh(0,1,K*R); 67 | np = [-Jp(2) ; Jp(1)]/norm([-Jp(2) ; Jp(1)]); 68 | dGdnp = (1i*K/4)*besselh(1,1,K*R)*(P-M)/R*np; 69 | J = norm(Jm)*norm(Jp); 70 | % Compute the operator 71 | Ke = Ke - GAUSS_WEIGHT(mm)*GAUSS_WEIGHT(pp)*Nu'*Nv*dGdnp*J; 72 | end 73 | end 74 | 75 | 76 | % AUTO INFLUENCE TERM 77 | % => No Singularity in this case, simply splitting the quadrature 78 | else 79 | % For now the number of GP is constant 80 | % integration over M (not modified) 81 | for mm=1:N_GAUSS_POINT 82 | u = GAUSS_POINT(mm); 83 | Nu = SHAPEFUNC(:,mm)'; 84 | dNu = DSHAPEFUNC(:,mm)'; 85 | Jm = [dNu*x_nodem dNu*y_nodem]; 86 | M = [Nu*x_nodem Nu*y_nodem]; 87 | % 88 | % The element P is split into two parts with M the common node 89 | % 90 | %-------------------------------------------------------------- 91 | % *** First element 92 | %-------------------------------------------------------------- 93 | N_GAUSS_POINT2 = mm*QuadAutoFactor; 94 | [GAUSS_POINT2,GAUSS_WEIGHT2] = gauleg(-1,u,N_GAUSS_POINT2); 95 | 96 | for pp=1:N_GAUSS_POINT2 97 | v = GAUSS_POINT2(pp); 98 | [Nv,dNv] = shape_function(v,Order); 99 | Jp = [dNv*x_nodep dNv*y_nodep]; 100 | P = [Nv*x_nodep Nv*y_nodep]; 101 | R = norm(P-M); 102 | %G = -i/4*besselh(0,1,K*R); 103 | np = [-Jp(2) ; Jp(1)]/norm([-Jp(2) ; Jp(1)]); 104 | dGdnp = (1i*K/4)*besselh(1,1,K*R)*(P-M)/R*np; 105 | J = norm(Jm)*norm(Jp); 106 | % Compute the operator 107 | Ke = Ke - GAUSS_WEIGHT(mm)*GAUSS_WEIGHT2(pp)*Nu'*Nv*dGdnp*J; 108 | end 109 | %-------------------------------------------------------------- 110 | % *** Second element 111 | %-------------------------------------------------------------- 112 | N_GAUSS_POINT2 = (N_GAUSS_POINT+1 - mm) * QuadAutoFactor; 113 | [GAUSS_POINT2,GAUSS_WEIGHT2] = gauleg(u,1,N_GAUSS_POINT2); 114 | 115 | for pp=1:N_GAUSS_POINT2 116 | v = GAUSS_POINT2(pp); 117 | [Nv,dNv] = shape_function(v,Order); 118 | Jp = [dNv*x_nodep dNv*y_nodep]; 119 | P = [Nv*x_nodep Nv*y_nodep]; 120 | R = norm(P-M); 121 | %G = -i/4*besselh(0,1,K*R); 122 | np = [-Jp(2) ; Jp(1)]/norm([-Jp(2) ; Jp(1)]); 123 | dGdnp = (1i*K/4)*besselh(1,1,K*R)*(P-M)/R*np; 124 | J = norm(Jm)*norm(Jp); 125 | % Compute the operator 126 | Ke = Ke - GAUSS_WEIGHT(mm)*GAUSS_WEIGHT2(pp)*Nu'*Nv*dGdnp*J; 127 | end 128 | end 129 | end 130 | end 131 | 132 | 133 | %-------------------------------------------------------------------------- 134 | % Single integration (Calling function with a single argument) 135 | %-------------------------------------------------------------------------- 136 | 137 | if nargin == 1 138 | for mm=1:N_GAUSS_POINT 139 | u = GAUSS_POINT(mm); 140 | Nu = SHAPEFUNC(:,mm)'; 141 | dNu = DSHAPEFUNC(:,mm)'; 142 | J = norm([dNu*x_nodem dNu*y_nodem]); 143 | M = [Nu*x_nodem Nu*y_nodem]; 144 | 145 | % Right hand side - incident plane wave 146 | Phi_inc = exp(1i*K*M(1)); 147 | 148 | % Compute the operator 149 | Ke = Ke + 0.5*GAUSS_WEIGHT(mm)*Nu'*Nu*J; 150 | Fe = Fe + GAUSS_WEIGHT(mm)*Nu'*Phi_inc*J; 151 | end 152 | end 153 | 154 | -------------------------------------------------------------------------------- /Library/Helmholtz_2D_BEM/L2/DBEM_Wall_Wall_BurtonMiller.m: -------------------------------------------------------------------------------- 1 | function [Ke,Fe,Re,Ve] = DBEM_Wall_Wall_BurtonMiller(m,p) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % Helmholtz equation BEM formulation (direct BEM) 4 | % Isoparametric high-order element (Lagrange polynomial) 5 | % Interpolation depends on order 6 | % L2->1, L3->2, ... 7 | % Right hand side: Diffraction by a plane wave 8 | % Formulation: 9 | 10 | % Using Burton Miller DBEM formulation with singularity substraction by 11 | % Bonnet 12 | % 1. Burton AJ, Miller GF. The application of integral equation methods to 13 | % the numerical solution of some exterior boundary-value problems. 1971 14 | % 2. Bonnet M, Guiggiani M. Galerkin BEM with direct evaluation of hyper- 15 | % singular integrals. 2003 16 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17 | 18 | global Order 19 | 20 | NrOfNodes = (Order+1); 21 | 22 | if nargin==0 23 | Ke = [1 NrOfNodes ones(1,NrOfNodes) 0]; 24 | return 25 | end 26 | 27 | global omega N_GAUSS_POINT alpha 28 | global ELEMENT NODE NODE_DATA 29 | global GAUSS_POINT GAUSS_WEIGHT SHAPEFUNC DSHAPEFUNC 30 | global N_DOF_ELEMENT 31 | 32 | RHO = NODE_DATA(1,ELEMENT(1,m)); 33 | C0 = NODE_DATA(2,ELEMENT(1,m)); 34 | K = (omega/C0); 35 | 36 | Ke = zeros(NrOfNodes,NrOfNodes); 37 | I3S = zeros(NrOfNodes,NrOfNodes); 38 | Fe = zeros(NrOfNodes,1); 39 | Re = zeros(NrOfNodes,NrOfNodes); 40 | Ve = zeros(NrOfNodes,1); 41 | 42 | % Density quadrature factor (For the auto-influence computation) 43 | QuadAutoFactor = 1; 44 | 45 | x_nodem = NODE(1,ELEMENT(:,m))'; 46 | y_nodem = NODE(2,ELEMENT(:,m))'; 47 | 48 | %-------------------------------------------------------------------------- 49 | % Double integration (Calling function with a double argument) 50 | %-------------------------------------------------------------------------- 51 | if nargin ==2; 52 | x_nodep = NODE(1,ELEMENT(:,p))'; 53 | y_nodep = NODE(2,ELEMENT(:,p))'; 54 | % Standard quadrature (elements do not coincide) 55 | if m~=p 56 | % integrating over M 57 | for mm=1:N_GAUSS_POINT 58 | u = GAUSS_POINT(mm); 59 | Nu = SHAPEFUNC(:,mm)'; 60 | dNu = DSHAPEFUNC(:,mm)'; 61 | Jm = [dNu*x_nodem dNu*y_nodem]; 62 | % integrating over P 63 | M = [Nu*x_nodem Nu*y_nodem]; 64 | for pp=1:N_GAUSS_POINT 65 | v = GAUSS_POINT(pp); 66 | Nv = SHAPEFUNC(:,pp)'; 67 | dNv = DSHAPEFUNC(:,pp)'; 68 | Jp = [dNv*x_nodep dNv*y_nodep]; 69 | P = [Nv*x_nodep Nv*y_nodep]; 70 | R = norm(P-M); 71 | nm = [-Jm(2) ; Jm(1)]/norm([-Jm(2) ; Jm(1)]); % Normale sortante du domaine de rayonnement en M 72 | np = [-Jp(2) ; Jp(1)]/norm([-Jp(2) ; Jp(1)]); 73 | G = -1i/4*besselh(0,1,K*R); 74 | dGdnp = (1i*K/4)*besselh(1,1,K*R)*(P-M)/R*np; 75 | J = norm(Jm)*norm(Jp); 76 | % Compute the operator 77 | Ke = Ke + GAUSS_WEIGHT(mm)*GAUSS_WEIGHT(pp)*(- Nu'*Nv*dGdnp*J - alpha*G*( K^2*Nu'*Nv*(nm'*np)*J - dNu'*dNv)); 78 | end 79 | end 80 | 81 | % AUTO INFLUENCE TERM 82 | % => No Singularity in this case, simply splitting the quadrature 83 | else 84 | % For now the number of GP is constant 85 | % integration over M (not modified) 86 | for mm=1:N_GAUSS_POINT 87 | u = GAUSS_POINT(mm); 88 | Nu = SHAPEFUNC(:,mm)'; 89 | dNu = DSHAPEFUNC(:,mm)'; 90 | Jm = [dNu*x_nodem dNu*y_nodem]; 91 | M = [Nu*x_nodem Nu*y_nodem]; 92 | 93 | % 94 | % The element P is split into two parts with M the common node 95 | % 96 | %-------------------------------------------------------------- 97 | % *** First element 98 | %-------------------------------------------------------------- 99 | N_GAUSS_POINT2 = mm*QuadAutoFactor; 100 | [GAUSS_POINT2,GAUSS_WEIGHT2] = gauleg(-1,u,N_GAUSS_POINT2); 101 | 102 | for pp=1:N_GAUSS_POINT2 103 | v = GAUSS_POINT2(pp); 104 | [Nv,dNv] = shape_function(v,Order); 105 | Jp = [dNv*x_nodep dNv*y_nodep]; 106 | P = [Nv*x_nodep Nv*y_nodep]; 107 | R = norm(P-M); 108 | % normals 109 | nm = [-Jm(2) ; Jm(1)]/norm([-Jm(2) ; Jm(1)]); % Normale sortante du domaine de rayonnement en M 110 | np = [-Jp(2) ; Jp(1)]/norm([-Jp(2) ; Jp(1)]); % Normale sortante du domaine de rayonnement en P 111 | % kernel 112 | G = -1i/4*besselh(0,1,K*R); 113 | dGdnp = (1i*K/4)*besselh(1,1,K*R)*(P-M)/R*np; 114 | % Jacobian 115 | J = norm(Jm)*norm(Jp); 116 | % Compute the operator 117 | f_uv = K^2*Nu'*Nv*(nm'*np)*J - dNu'*dNv; 118 | % I2 119 | Ke = Ke + GAUSS_WEIGHT(mm)*GAUSS_WEIGHT2(pp)*( -Nu'*Nv*dGdnp*J); 120 | % I3 121 | Ke = Ke - GAUSS_WEIGHT(mm)*GAUSS_WEIGHT2(pp)*alpha*G*f_uv; 122 | % I3R - regular part -> substracting singularity 123 | Ke = Ke + GAUSS_WEIGHT(mm)*GAUSS_WEIGHT2(pp)*alpha/(2*pi)*f_uv*log(abs(u-v)); 124 | end 125 | %-------------------------------------------------------------- 126 | % *** Second element 127 | %-------------------------------------------------------------- 128 | 129 | N_GAUSS_POINT2 = (N_GAUSS_POINT+1 - mm) * QuadAutoFactor; 130 | [GAUSS_POINT2,GAUSS_WEIGHT2] = gauleg(u,1,N_GAUSS_POINT2); 131 | 132 | for pp=1:N_GAUSS_POINT2 133 | v = GAUSS_POINT2(pp); 134 | [Nv,dNv] = shape_function(v,Order); 135 | Jp = [dNv*x_nodep dNv*y_nodep]; 136 | P = [Nv*x_nodep Nv*y_nodep]; 137 | R = norm(P-M); 138 | % normals 139 | nm = [-Jm(2) ; Jm(1)]/norm([-Jm(2) ; Jm(1)]); % Normale sortante du domaine de rayonnement en M 140 | np = [-Jp(2) ; Jp(1)]/norm([-Jp(2) ; Jp(1)]); % Normale sortante du domaine de rayonnement en P 141 | % Kernel 142 | G = -1i/4*besselh(0,1,K*R); 143 | dGdnp = (1i*K/4)*besselh(1,1,K*R)*(P-M)/R*np; 144 | % Jacobian 145 | J = norm(Jm)*norm(Jp); 146 | % Compute the operator 147 | f_uv = K^2*Nu'*Nv*(nm'*np)*J - dNu'*dNv; 148 | % I2 149 | Ke = Ke + GAUSS_WEIGHT(mm)*GAUSS_WEIGHT2(pp)*( -Nu'*Nv*dGdnp*J); 150 | % I3 151 | Ke = Ke - GAUSS_WEIGHT(mm)*GAUSS_WEIGHT2(pp)*alpha*G*f_uv; 152 | % I3R - regular part -> substracting singularity 153 | Ke = Ke + GAUSS_WEIGHT(mm)*GAUSS_WEIGHT2(pp)*alpha/(2*pi)*f_uv*log(abs(u-v)); 154 | end 155 | end 156 | 157 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 158 | % Computing the singular part 159 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 160 | %-alpha/(2*pi)* log(u-v)*f(u,v) 161 | n_gauss_point_KSI = N_GAUSS_POINT*QuadAutoFactor; 162 | n_gauss_point_ZETA = n_gauss_point_KSI; 163 | 164 | % Classical GP and Specific Log GP from 0 to 1 165 | [nodesNor,weightsNor] = gauleg(0,1,12); 166 | nodesLog = [ 0.006548722279080035, 0.03894680956045022, 0.0981502631060046, 0.1811385815906331, 0.2832200676673157, 0.398434435164983, 0.5199526267791299, 0.6405109167754819, 0.7528650118926111, 0.850240024421055, 0.926749682988251, 0.977756129778486]; 167 | weightsLog = [-0.09319269144393, -0.1497518275763289, -0.166557454364573, -0.1596335594369941, -0.1384248318647479, -0.1100165706360573, -0.07996182177673273, -0.0524069547809709, -0.03007108900074863, -0.01424924540252916, -0.004899924710875609, -0.000834029009809656]; 168 | 169 | epsi = (24/N_GAUSS_POINT)/2; 170 | 171 | % ksi : -1 -> 1 172 | [gauss_point_KSI,gauss_weight_KSI] = gauleg(-1,1,n_gauss_point_KSI); 173 | % zetaa goes from 0 to 2 (in 2 steps) 174 | [gauss_point_ZETA,gauss_weight_ZETA] = gauleg(epsi,2,n_gauss_point_ZETA); 175 | 176 | % integration over ksi from 0 to 2 177 | for mm=1:n_gauss_point_KSI 178 | ksi = gauss_point_KSI(mm) ; 179 | %----------------------------------------------------- 180 | % LOG GAUSS POINTS (change of variable, we integrate from 0 to 1) 181 | % zeta: 0 -> epsi 182 | for pp=1:12 183 | I3S = I3S + gauss_weight_KSI(mm)*epsi*( fobonnet(epsi*nodesLog(pp),ksi,m)*weightsLog(pp) + fobonnet(epsi*nodesNor(pp),ksi,m)*log(epsi)*weightsNor(pp) ); 184 | end 185 | %----------------------------------------------------- 186 | % SECOND PART, CLASSICAL GAUSS QUADRATURE 187 | % zeta: epsi -> 2-ksi 188 | for pp=1:n_gauss_point_ZETA 189 | zetaa = gauss_point_ZETA(pp); 190 | I3S = I3S + gauss_weight_KSI(mm)*gauss_weight_ZETA(pp)*log(zetaa)*fobonnet(zetaa,ksi,m); 191 | end 192 | end 193 | 194 | % adding the term -int(int(alpha/(2.d0*pi)*f_uv*dlog(dabs(u-v)),u,-1,1),v,-1,1) 195 | Ke = Ke - alpha/(2*pi)*I3S; 196 | end 197 | end 198 | 199 | %-------------------------------------------------------------------------- 200 | % Single integration (Calling function with a single argument) 201 | %-------------------------------------------------------------------------- 202 | 203 | if nargin == 1 204 | for mm=1:N_GAUSS_POINT 205 | u = GAUSS_POINT(mm); 206 | Nu = SHAPEFUNC(:,mm)'; 207 | dNu = DSHAPEFUNC(:,mm)'; 208 | J = ([dNu*x_nodem dNu*y_nodem]); 209 | nm = [-J(2) ; J(1)]/norm([-J(2) ; J(1)]); % Normale sortante du domaine de rayonnement en M 210 | J = norm(J); 211 | M = [Nu*x_nodem Nu*y_nodem]; 212 | 213 | % Right hand side - incident plane wave 214 | Phi_inc = exp(1i*K*M(1)); 215 | dPhi_incdnm = nm.'*[1i*K*Phi_inc ; 0]; 216 | 217 | % Compute the operator 218 | Ke = Ke + 0.5*GAUSS_WEIGHT(mm)*(Nu'*Nu)*J; 219 | Fe = Fe + GAUSS_WEIGHT(mm)*Nu'*(Phi_inc + alpha*dPhi_incdnm)*J; 220 | end 221 | end 222 | 223 | end 224 | %$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 225 | function [out] = fobonnet(zetaa,ksi,m) 226 | 227 | global omega Order NODE ELEMENT 228 | 229 | x_nodem = NODE(1,ELEMENT(:,m))'; 230 | y_nodem = NODE(2,ELEMENT(:,m))'; 231 | 232 | K = (omega/340); 233 | 234 | %!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 235 | %! Computing f(u(ksi,zetaa),v(ksi,zetaa))+ f(v(ksi,zetaa),u(ksi,zetaa)) 236 | %!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 237 | u = ksi - zetaa/2 - ksi*zetaa/2; 238 | v = ksi + zetaa/2 - ksi*zetaa/2; 239 | 240 | % Geometry 241 | [Nu,dNu] = shape_function(u,Order); 242 | [Nv,dNv] = shape_function(v,Order); 243 | Jm = [dNu*x_nodem dNu*y_nodem]; 244 | Jp = [dNv*x_nodem dNv*y_nodem]; 245 | 246 | % Normals 247 | nm = [-Jm(2) ; Jm(1)]/norm([-Jm(2) ; Jm(1)]); 248 | np = [-Jp(2) ; Jp(1)]/norm([-Jp(2) ; Jp(1)]); 249 | 250 | % Points 251 | M = [Nu*x_nodem Nu*y_nodem]; 252 | P = [Nv*x_nodem Nv*y_nodem]; 253 | 254 | % Jacobien 255 | J = norm(Jm)*norm(Jp); 256 | 257 | fuv = K^2*Nu'*Nv*(nm'*np)*J - dNu'*dNv; 258 | fvu = K^2*Nv'*Nu*(nm'*np)*J - dNv'*dNu; 259 | 260 | out = (fuv + fvu)*(1-zetaa/2); 261 | 262 | end 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | --------------------------------------------------------------------------------