├── .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 |
--------------------------------------------------------------------------------