├── .gitattributes ├── LICENSE ├── README.md ├── elasticity ├── 3rd_party_elasticity_codes_for_testing │ ├── code_acfk │ │ ├── README │ │ ├── add_paths.m │ │ ├── coordinates.dat │ │ ├── dirichlet.dat │ │ ├── elements.dat │ │ ├── f.m │ │ ├── fem_lame3d.m │ │ ├── g.m │ │ ├── neumann.dat │ │ ├── show.m │ │ ├── stima.m │ │ └── u_d.m │ ├── code_k │ │ ├── ._kelas3drhs.m │ │ ├── ._kelas3drhsn.m │ │ ├── ._kelas3dshow.m │ │ ├── ._kpde2dumsh.m │ │ ├── ._kpde3dumsh.m │ │ ├── ._kpde_elas.m │ │ ├── Copyrights.txt │ │ ├── add_paths.m │ │ ├── demo_elas.m │ │ ├── demo_scalar.m │ │ ├── kelas2d_cook.m │ │ ├── kelas2drhs.m │ │ ├── kelas2drhsn.m │ │ ├── kelas2dshow.m │ │ ├── kelas2dstf.m │ │ ├── kelas2dvmes.m │ │ ├── kelas3d_exple1.m │ │ ├── kelas3drhs.m │ │ ├── kelas3drhsn.m │ │ ├── kelas3dshow.m │ │ ├── kelas3dstf.m │ │ ├── kelas3dvmes.m │ │ ├── kpde2dgphi.m │ │ ├── kpde2dmss.m │ │ ├── kpde2drhs.m │ │ ├── kpde2drhsn.m │ │ ├── kpde2dstf.m │ │ ├── kpde2dumsh.m │ │ ├── kpde3dgphi.m │ │ ├── kpde3dmss.m │ │ ├── kpde3drhs.m │ │ ├── kpde3drhsn.m │ │ ├── kpde3dshow.m │ │ ├── kpde3dstf.m │ │ └── kpde3dumsh.m │ └── code_rv │ │ ├── library_meshing │ │ ├── deleteRepeatedRows.m │ │ ├── entryInWhichRows.m │ │ ├── getEdges.m │ │ ├── get_boundary_edges.m │ │ ├── get_boundary_faces.m │ │ ├── get_boundary_nodes.m │ │ ├── get_edges.m │ │ ├── get_faces.m │ │ ├── get_midpoints.m │ │ ├── refinement_uniform.m │ │ ├── refinement_uniform3D.m │ │ ├── refinement_uniform_2D.m │ │ ├── refinement_uniform_3D.m │ │ ├── signs_edges.m │ │ ├── signs_faces.m │ │ └── tetrarefine3.m │ │ ├── library_nodal_elements_rv │ │ ├── create_2D_mesh.m │ │ ├── display_assembly_times.m │ │ ├── mass_matrixP1_2D.m │ │ ├── mass_matrixP1_2D_elasticity.m │ │ ├── mass_matrixP1_3D.m │ │ ├── mass_matrixP1_3D_elasticity.m │ │ ├── mass_tensorP1_2D.m │ │ ├── mesh3D.mat │ │ ├── stiffness_matrixP1_2D.m │ │ ├── stiffness_matrixP1_2D_elasticity.m │ │ ├── stiffness_matrixP1_3D.m │ │ ├── stiffness_matrixP1_3D_elasticity.m │ │ ├── stiffness_matrixP2_2D.m │ │ ├── stiffness_matrixQ1_3D_elasticity.m │ │ ├── stiffness_tensorP1_2D.m │ │ └── visualize_mesh.m │ │ ├── library_vectorization │ │ ├── amav.m │ │ ├── amdet.m │ │ ├── aminv.m │ │ ├── amsm.m │ │ ├── amsv.m │ │ ├── amt.m │ │ ├── amtam.m │ │ ├── astam.m │ │ ├── avtam.m │ │ ├── avtamav.m │ │ ├── avtav.m │ │ ├── conv_ma2av.m │ │ ├── conv_sm2am.m │ │ ├── copy_matrix_to_3Dmatrix.m │ │ ├── phider.m │ │ ├── quadratic_form_elementwise.m │ │ ├── shapeder.m │ │ ├── shapefun.m │ │ ├── smamt.m │ │ └── svamt.m │ │ └── library_visualization │ │ ├── draw_edges.m │ │ ├── draw_vertices.m │ │ ├── show_boundary_nodes.m │ │ ├── show_constant_scalar.m │ │ ├── show_constant_scalar_frame.asv │ │ ├── show_constant_scalar_frame.m │ │ ├── show_edges.m │ │ ├── show_elements.m │ │ ├── show_mesh.m │ │ ├── show_nodal_scalar.m │ │ ├── show_nodal_scalar_frame.m │ │ ├── show_nodes.m │ │ ├── show_points.m │ │ ├── show_points_blue.m │ │ ├── show_points_red.m │ │ ├── show_vertices.m │ │ └── show_vertices_red.m ├── add_paths.m ├── comparison_assembly_P1_2D_elasticity.m ├── comparison_assembly_P1_3D_elasticity.m ├── comparison_fem_3D_elasticity.m ├── elasticity_2D │ ├── draw_displacement.m │ ├── draw_mesh.m │ ├── elastic_stiffness_matrix.m │ ├── elasticity_assembly_test.m │ ├── elasticity_fem.m │ ├── isOctave.m │ ├── local_basis_surface.m │ ├── local_basis_volume.m │ ├── mesh_P1.m │ ├── mesh_P2.m │ ├── mesh_Q1.m │ ├── mesh_Q2.m │ ├── quadrature_surface.m │ ├── quadrature_volume.m │ ├── vector_traction.m │ └── vector_volume.m └── elasticity_3D │ ├── draw_displacement.m │ ├── draw_mesh.m │ ├── elastic_stiffness_matrix.m │ ├── elasticity_assembly_test.m │ ├── elasticity_fem.m │ ├── isOctave.m │ ├── local_basis_surface.m │ ├── local_basis_volume.m │ ├── mesh_P1.m │ ├── mesh_P2.m │ ├── mesh_Q1.m │ ├── mesh_Q2.m │ ├── quadrature_surface.m │ ├── quadrature_volume.m │ ├── vector_traction.m │ └── vector_volume.m └── plasticity ├── plasticity_DP_2D ├── constitutive_problem.m ├── draw_mesh.m ├── draw_quantity.m ├── elastic_stiffness_matrix.m ├── enlarge_axis.m ├── isOctave.m ├── local_basis_volume.m ├── mesh_P1.m ├── mesh_P2.m ├── mesh_Q1.m ├── mesh_Q2.m ├── plasticity_DP_fem.m ├── quadrature_volume.m ├── test_load_paths.m └── transformation.m ├── plasticity_DP_3D ├── constitutive_problem.m ├── draw_mesh.m ├── draw_quantity.m ├── elastic_stiffness_matrix.m ├── isOctave.m ├── local_basis_volume.m ├── mesh_P1.m ├── mesh_P2.m ├── mesh_Q1.m ├── mesh_Q2.m ├── plasticity_DP_fem.m ├── quadrature_volume.m └── transformation.m ├── plasticity_VM_2D ├── constitutive_problem.m ├── draw_mesh.m ├── draw_quantity.m ├── elastic_stiffness_matrix.m ├── isOctave.m ├── local_basis_surface.m ├── local_basis_volume.m ├── mesh_P1.m ├── mesh_P2.m ├── mesh_Q1.m ├── mesh_Q2.m ├── plasticity_VM_fem.m ├── quadrature_surface.m ├── quadrature_volume.m ├── transformation.m └── vector_traction.m └── plasticity_VM_3D ├── constitutive_problem.m ├── draw_mesh.m ├── draw_quantity.m ├── elastic_stiffness_matrix.m ├── enlarge_axis.m ├── isOctave.m ├── local_basis_surface.m ├── local_basis_volume.m ├── mesh_P1.m ├── mesh_P2.m ├── mesh_Q1.m ├── mesh_Q2.m ├── plasticity_VM_fem.m ├── quadrature_surface.m ├── quadrature_volume.m ├── transformation.m └── vector_traction.m /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2018, Martin Cermak, Stanislav Sysala, Jan Valdman 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems 2 | ## Authors 3 | Martin Cermak (UGN Ostrava), Stanislav Sysala (UGN Ostrava), Jan Valdman (UTIA Praha) 4 | 5 | These codes are an essential part of the paper "M. Cermak, S. Sysala, J. Valdman: Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems. Applied Mathematics and Computation 355, (2019) pp. 595-614, DOI: 10.1016/j.amc.2019.02.054" available also at https://arxiv.org/pdf/1805.04155.pdf 6 | 7 | The implementation is rather universal for various elastoplastic models, finite elements, and quadrature rules. It provides several computing benchmarks including 8 | (a) elastic and elastoplastic models with von Mises or Drucker-Prager yield criteria; 9 | (b) finite element implementations of P1, P2, Q1, Q2 elements in both 2D and 3D. 10 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_acfk/README: -------------------------------------------------------------------------------- 1 | Change log: 2 | 3 | 03/21/2003 - A new version of the data file ELEMENTS.DAT 4 | is included which fixes the orientation of two tetrahedra. 5 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_acfk/add_paths.m: -------------------------------------------------------------------------------- 1 | % This script adds the absolute location of 2 | % the shared functions to the path 3 | 4 | path1 = cd; 5 | cd .. 6 | path2 = cd; 7 | if ( isunix ) 8 | addpath(genpath([path2])); 9 | else 10 | addpath(genpath([path2])); 11 | end 12 | cd(path1) -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_acfk/f.m: -------------------------------------------------------------------------------- 1 | function volforce = f(x) 2 | %F Volume force in considered domain. 3 | % Y = F(X) returns values of forces at N discrete points in the considered 4 | % domain. This input data has to be chosen by the user. X has dimension N 5 | % x 3 and Y has dimension N x 3. 6 | % 7 | % 8 | % See also FEM_LAME3D. 9 | 10 | % J. Alberty, C. Carstensen, S. A. Funken, and R. Klose 07-03-00 11 | % File in $(HOME)/acfk/fem_lame3d/angle/ 12 | 13 | volforce=zeros(size(x,1),3); 14 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_acfk/g.m: -------------------------------------------------------------------------------- 1 | function sforce = g(x,n) 2 | %G Data on the Neumann boundary 3 | % Y = G(X,NORMAL) returns values of the normal-derivative at N discrete 4 | % points on the Neumann boundary. This input data has to be choosen 5 | % by the user. X has dimension N x 3, NORMAL has dimension N x 3 6 | % containing the normal direction of the boundary at the corresponding 7 | % point, and Y has dimension N x 3. 8 | % 9 | % 10 | % See also FEM_LAME3D. 11 | 12 | % J. Alberty, C. Carstensen, S. A. Funken, and R. Klose 07-03-00 13 | % File in $(HOME)/acfk/fem_lame3d/angle/ 14 | 15 | sforce=zeros(size(x,1),3); 16 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_acfk/show.m: -------------------------------------------------------------------------------- 1 | function show(elements,dirichlet,neumann,coordinates,u,lambda,mu) 2 | %SHOW Plots three-dimensional solution 3 | % SHOW(ELEMENTS,DIRICHLET,NEUMANN,COORDINATES,U,LAMBDA,MU) plots the 4 | % strained mesh and visualizes the stresses in grey tones. 5 | % 6 | % 7 | % See also FEM_LAME3D. 8 | 9 | % J. Alberty, C. Carstensen, S. A. Funken, and R. Klose 07-03-00 10 | % File in $(HOME)/acfk/fem_lame3d/angle/ 11 | 12 | E=zeros(4*size(elements,1),3); 13 | C=zeros(size(elements,1),1); 14 | for j=1:size(elements,1) 15 | PhiGrad=[1,1,1,1;coordinates(elements(j,:),:)']\[zeros(1,3);eye(3)]; 16 | U_Grad = u([1;1;1]*3*elements(j,:)-[2;1;0]*[1,1,1,1])*PhiGrad; 17 | SIGMA = lambda * trace(U_Grad)*eye(3)+mu*(U_Grad + U_Grad'); 18 | C(j) = sqrt(sum(eig(SIGMA).^2)); 19 | end 20 | Area = zeros(size(elements,1),1); 21 | AreaOmega = zeros(max(max(elements)),1); 22 | AvC = zeros(max(max(elements)),1); 23 | for j=1:size(elements,1) 24 | Area = det([1,1,1,1;coordinates(elements(j,:),:)'])/6; 25 | AreaOmega(elements(j,:))=AreaOmega(elements(j,:))+Area; 26 | AvC(elements(j,:)) = AvC(elements(j,:))+Area*[1;1;1;1]*C(j); 27 | end 28 | AvC = AvC./AreaOmega; 29 | E=[dirichlet;neumann]; 30 | factor=100.0; 31 | %colormap(1-gray); 32 | trisurf(E,factor*u(1:3:size(u,1))+coordinates(:,1), ... 33 | factor*u(2:3:size(u,1))+coordinates(:,2), ... 34 | factor*u(3:3:size(u,1))+coordinates(:,3),AvC,'facecolor','interp'); 35 | view(-50,35) 36 | axis equal; axis([-10 70 -100 20 0 40]) 37 | xlabel('x'); ylabel('y'); zlabel('z'); 38 | 39 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_acfk/stima.m: -------------------------------------------------------------------------------- 1 | function stima = stima(vertices,lambda,mu) 2 | %STIMA Computes element stiffness matrix for tetraeder. 3 | % M = STIMA(X,LAMBDA,MU) computes element stiffness matrix for 4 | % tetraeder. The coordinates of the vertices are stored in X. LAMBDA 5 | % and MU are the Lame constants. 6 | % 7 | % This routine should not be modified. 8 | % 9 | % 10 | % See also FEM_LAME3D. 11 | 12 | % J. Alberty, C. Carstensen and S. A. Funken 07-03-00 13 | % File in $(HOME)/acfk/fem_lame3d/angle/ 14 | 15 | PhiGrad = [1,1,1,1;vertices']\[zeros(1,3);eye(3)]; 16 | R = zeros(6,12); 17 | R([1,4,5],1:3:10) = PhiGrad'; 18 | R([4,2,6],2:3:11) = PhiGrad'; 19 | R([5,6,3],3:3:12) = PhiGrad'; 20 | C([1:3],[1:3]) = lambda*ones(3,3)+2*mu*eye(3); 21 | C([4:6],[4:6]) = mu*eye(3); 22 | stima = det([1,1,1,1;vertices'])/6*R'*C*R; 23 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_acfk/u_d.m: -------------------------------------------------------------------------------- 1 | function [W,M] = u_d(x) 2 | %U_D Data on the Dirichlet boundary 3 | % [W,M] = U_D(X) returns at N discrete points on the Dirichlet boundary 4 | % the direction for which the dispacement is given and the corresponding 5 | % values. If U is the displacement vector the Dirichlet boundary condition 6 | % is given by M*U = W. This input data has to be choosen by the user. X 7 | % has dimension N x 3, W has dimension 3*N x 1, and M has dimension 3*N 8 | % x 3. 9 | % 10 | % 11 | % See also FEM_LAME3D. 12 | 13 | % J. Alberty, C. Carstensen, S. A. Funken, and R. Klose 07-03-00 14 | % File in $(HOME)/acfk/fem_lame3d/angle/ 15 | 16 | M = zeros(3*size(x,1),3); 17 | W = zeros(3*size(x,1),1); 18 | M(1:3:end,1) = 1; 19 | M(2:3:end,2) = 1; 20 | M(3:3:end,3) = 1; 21 | W(3*find(x(:,2)<-50)) = 0.1; 22 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/._kelas3drhs.m: -------------------------------------------------------------------------------- 1 | Mac OS X  2FxMATFMATLATTRxx -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/._kelas3drhsn.m: -------------------------------------------------------------------------------- 1 | Mac OS X  2FxMATFMATLATTRxx -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/._kelas3dshow.m: -------------------------------------------------------------------------------- 1 | Mac OS X  2FxMATFMATLATTRxx -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/._kpde2dumsh.m: -------------------------------------------------------------------------------- 1 | Mac OS X  2FxMATFMATLATTRxx -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/._kpde3dumsh.m: -------------------------------------------------------------------------------- 1 | Mac OS X  2FxMATFMATLATTRxx -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/._kpde_elas.m: -------------------------------------------------------------------------------- 1 | Mac OS X  2FxMATFMATLATTRxx -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/Copyrights.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Jonas KOKO 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | * Neither the name of the nor the names 14 | of its contributors may be used to endorse or promote products derived 15 | from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/add_paths.m: -------------------------------------------------------------------------------- 1 | % This script adds the absolute location of 2 | % the shared functions to the path 3 | 4 | path1 = cd; 5 | cd .. 6 | path2 = cd; 7 | if ( isunix ) 8 | addpath(genpath([path2])); 9 | else 10 | addpath(genpath([path2])); 11 | end 12 | cd(path1) -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/demo_scalar.m: -------------------------------------------------------------------------------- 1 | %---------------------------------------- 2 | % Scalar problem 2D/3D 3 | % -\Delta u=f in \Omega=(0,1)^d 4 | % u=0 on boundary 5 | % 2D: f=-2x(x-1)-2y(y-1); 6 | % u_{exact}= xy(x-1)(y-1) 7 | % 3D: f=-2xy(x-1)(y-1)-2yz(y-1)(z-1)-2xz(x-1)(z-1); 8 | % u_{exact}= xyz(x-1)(y-1)(z-1) 9 | %---------------------------------------- 10 | % 11 | d=3; % dimension 12 | nx=9; % number of points in each dimension 13 | % mesh generation 14 | if (d==2) 15 | [p,t,pbx,pby]=kpde2dumsh(0,1,0,1,nx,nx); 16 | ibcx=union(pbx(:,1),pbx(:,2)); ibcy= union(pby(:,1),pby(:,2)); 17 | ibcd=union(ibcx,ibcy); 18 | clear ibcx ibcy 19 | elseif (d==3) 20 | [p,t,pbx,pby,pbz]=kpde3dumsh(0,1,0,1,0,1,nx,nx,nx); 21 | ibcx=union(pbx(:,1),pbx(:,2)); ibcy=union(pby(:,1),pby(:,2)); 22 | ibcz=union(pbz(:,1),pbz(:,2)); ibcd=union(ibcx,union(ibcy,ibcz)); 23 | clear ibcx ibcy ibcz 24 | else 25 | error('The value of d is not valid') 26 | end 27 | 28 | np=size(p,1); nt=size(t,1); 29 | fprintf('Dimension :%3d\n',d) 30 | fprintf('Number of vertices :%5d\n',np) 31 | fprintf('Number of elements :%5d\n',nt) 32 | 33 | % Right-hand side / exact solution 34 | if (d==2) 35 | x=p(:,1); y=p(:,2); ue=x.*y.*(x-1).*(y-1); 36 | fh=-2*x.*(x-1)-2*y.*(y-1); 37 | clear x y 38 | else 39 | x=p(:,1); y=p(:,2); z=p(:,3); ue=x.*y.*z.*(x-1).*(y-1).*(z-1); 40 | fh=-2*x.*y.*(x-1).*(y-1)-2*y.*z.*(y-1).*(z-1)-2*x.*z.*(x-1).*(z-1); 41 | clear x y z 42 | end 43 | 44 | % Assembly of matrices and rhs 45 | if (d==2) 46 | K=kpde2dstf(p,t,1); 47 | M=kpde2dmss(p,t,1); 48 | f=kpde2drhs(p,t,fh); 49 | else 50 | K=kpde3dstf(p,t,1); 51 | M=kpde3dmss(p,t,1); 52 | f=kpde3drhs(p,t,fh); 53 | end 54 | 55 | % Boundary conditions (penalization) 56 | K(ibcd,ibcd)=K(ibcd,ibcd)+10^15*speye(length(ibcd)); 57 | f(ibcd)=0; 58 | 59 | % Solution (Gaussian elimination) 60 | u=K\f; 61 | 62 | % Visualisation 63 | if (d==2) 64 | trisurf(t,p(:,1),p(:,2),u,'facecolor','interp') 65 | grid off, colorbar('horiz') 66 | else 67 | pt=(p(t(:,1),:)+p(t(:,2),:)+p(t(:,3),:)+p(t(:,4),:))/4; 68 | it=find(pt(:,2)>=1/2); 69 | kpde3dshow(p,t,u,it) 70 | end 71 | 72 | % Approximate L^2-error 73 | du=u-ue; err=sqrt(du'*M*du); 74 | fprintf('Approximate L^2-error : %12.8e \n',err) 75 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas2d_cook.m: -------------------------------------------------------------------------------- 1 | % 2 | % Elasticité linéaire 2D: Membrane de Cook 3 | % Solution par élimination de Gauss 4 | %---------------------------------------------------------- 5 | % constantes 6 | E=30000; nu=0.4; 7 | Penalty=10^15*E; 8 | 9 | % chargement du maillage 10 | load cook995 p t ibcd ibcneum 11 | n=size(p,1); nn=2*n; 12 | 13 | % d.d.l. de Dirichlet 14 | nnb=2*length(ibcd); 15 | ibc=zeros(nnb,1); ibc(1:2:end)=2*ibcd-1; ibc(2:2:end)=2*ibcd; 16 | 17 | % assemblage de la matrice et second membre 18 | K=kelas2drgd(p,t,E,nu); 19 | f1=zeros(n,1); f2=-.75*ones(n,1); 20 | f=kelas2drhs(p,t,f1,f2); 21 | g=kelas2drhsn(p,ibcneum,0,10); 22 | clear ibcn ibcn1 ibcn2 23 | 24 | % conditions aux limites de Dirichlet par pénalisation 25 | K(ibc,ibc)=K(ibc,ibc)+Penalty*speye(nnb); 26 | b=f+g; b(ibc)=0; 27 | 28 | % solution par élimination de Gauss 29 | u=K\b; 30 | 31 | % contraintes de Von Mises, visualisation 32 | s=kelas2dvmes(p,t,u,E,nu); 33 | colormap(1-gray), kelas2dshow(p,t,u,20,s) 34 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas2drhs.m: -------------------------------------------------------------------------------- 1 | function b=kelas2drhs(p,t,fx,fy) 2 | %KELAS2DRHS Assembles the right-hand side with P1 finite element 3 | %-------------------------------------------------------------------- 4 | % b=kelas2drhs(p,t,fx,fy) 5 | % 6 | % Input: 7 | % p : Nodes coordinates, np*2 8 | % t : Triangle vertices, nt*3 9 | % f : Source term, column vector np*1 10 | % 11 | % Output: 12 | % b : Right-hand side, np*1 13 | %-------------------------------------------------------------------- 14 | % (c) J. Koko, LIMOS 2006-2015, koko@isima.fr 15 | %-------------------------------------------------------------------- 16 | np=size(p,1); nt=size(t,1); nn=2*np; 17 | 18 | % f at centers of mass 19 | f1=(fx(t(:,1))+fx(t(:,2))+fx(t(:,3)))/3; 20 | f2=(fy(t(:,1))+fy(t(:,2))+fy(t(:,3)))/3; 21 | 22 | % triangles area 23 | area=kpde2dgphi(p,t); 24 | 25 | % assembly 26 | f1=f1.*area/3; f2=f2.*area/3; 27 | b=zeros(nn,1); 28 | b(1:2:nn)=full(sparse(t(:,1),1,f1,np,1)+sparse(t(:,2),1,f1,np,1)... 29 | +sparse(t(:,3),1,f1,np,1)); 30 | b(2:2:nn)=full(sparse(t(:,1),1,f2,np,1)+sparse(t(:,2),1,f2,np,1)... 31 | +sparse(t(:,3),1,f2,np,1)); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas2drhsn.m: -------------------------------------------------------------------------------- 1 | function b=kelas2drhsn(p,eneum,g1,g2) 2 | %KELAS2DRHSN Assembles the RHS contribution of Neumann boundary conditions. 3 | %-------------------------------------------------------------------- 4 | % b=kelas2drhsn(p,eneum,gx,gy) 5 | % 6 | % input: 7 | % p : Nodes coordinates, np*2 8 | % fneum : Boundary edges, ne*2 9 | % g1,g2 : Neumann boundary condition, np*1 10 | % g ~=0 on Neumann nodes 11 | % 12 | % Output: 13 | % b : Right-hand side, 2*np*1 14 | %-------------------------------------------------------------------- 15 | % (c) J. Koko, LIMOS 2006-2015, koko@isima.fr 16 | %-------------------------------------------------------------------- 17 | np=size(p,1); ni=size(eneum,1); 18 | 19 | % edges length 20 | xy=p(eneum(:,2),:)-p(eneum(:,1),:); le=sqrt(sum(xy.^2,2)); 21 | 22 | % g at centers of mass 23 | gh1=(g1(eneum(:,1))+g1(eneum(:,2))).*le/4; 24 | gh2=(g2(eneum(:,1))+g2(eneum(:,2))).*le/4; 25 | 26 | % assembly 27 | b=zeros(2*np,1); 28 | b(1:2:end)=full(sparse(eneum(:,1),1,gh1,np,1)+sparse(eneum(:,2),1,gh1,np,1)); 29 | b(2:2:end)=full(sparse(eneum(:,1),1,gh2,np,1)+sparse(eneum(:,2),1,gh2,np,1)); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas2dshow.m: -------------------------------------------------------------------------------- 1 | function kelas2dshow(p,t,u,mag,sf) 2 | %KELAS2DSHOW Visualisation du maillage déformé et/ou des contraintes 3 | %-------------------------------------------------------------------- 4 | np=size(p,1); pu=zeros(np,2); 5 | pu(:,1)=p(:,1)+mag*u(1:2:end); pu(:,2)=p(:,2)+mag*u(2:2:end); 6 | 7 | % 2. maillage déformé + contraintes en niveau de gris 8 | trisurf(t,pu(:,1),pu(:,2),zeros(np,1),sf,'facecolor','interp') 9 | colorbar('East'), view(2), return 10 | 11 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas2dstf.m: -------------------------------------------------------------------------------- 1 | function R=kelas2dstf(p,t,Young,nu) 2 | %KELAS2DSTF Assembles the stiffness matrix for 2D linear elasticity 3 | % with P1 finite element 4 | %-------------------------------------------------------------------- 5 | % R=kelas2dstf(p,t,Young,nu) 6 | % 7 | % Input: 8 | % p : Nodes coordinates, np*2 9 | % t : Triangle vertices, nt*3 10 | % Young : Young modulus (scalar) 11 | % nu : Poisson ratio (scalar) 12 | % 13 | % Output: 14 | % R : Stiffness matrix, sparse (2*np)*(2*np) 15 | % symmetric, positive semidefinite 16 | %-------------------------------------------------------------------- 17 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 18 | %-------------------------------------------------------------------- 19 | np=size(p,1); nn=2*np; nt=size(t,1); 20 | mu=.5*Young/(1+nu); lam=Young*nu/((1+nu)*(1-2*nu)); 21 | C=[lam+2*mu lam 0; 22 | lam lam+2*mu 0; 23 | 0 0 mu]; 24 | % gradients of basis functions 25 | [ar,g1,g2,g3]=kpde2dgphi(p,t); 26 | B=cell(3,6); [B{:,:}]=deal(sparse(nt,1)); 27 | B{1,1}=g1(:,1); B{1,3}=g2(:,1); B{1,5}=g3(:,1); 28 | B{2,2}=g1(:,2); B{2,4}=g2(:,2); B{2,6}=g3(:,2); 29 | B{3,1}=g1(:,2); B{3,2}=g1(:,1); B{3,3}=g2(:,2); 30 | B{3,4}=g2(:,1); B{3,5}=g3(:,2); B{3,6}=g3(:,1); 31 | E=cell(3,6); 32 | for i=1:3 33 | for j=1:6 34 | E{i,j}=C(i,1)*B{1,j}+C(i,2)*B{2,j}+C(i,3)*B{3,j}; 35 | end 36 | end 37 | inodes=[1 1 2 2 3 3]; icomps=[1 2 1 2 1 2]; 38 | R=sparse(nn,nn); 39 | % under-diagonal entries 40 | for i=1:6 41 | ik=2*(inodes(i)-1)+icomps(i); it=2*(t(:,inodes(i))-1)+icomps(i); 42 | for j=1:i-1 43 | jl=2*(inodes(j)-1)+icomps(j); jt=2*(t(:,inodes(j))-1)+icomps(j); 44 | Rij=B{1,ik}.*E{1,jl}+B{2,ik}.*E{2,jl}+B{3,ik}.*E{3,jl}; 45 | R=R+sparse(it,jt,ar.*Rij,nn,nn); 46 | end 47 | end 48 | % transpose 49 | R=R+R.'; 50 | % diagonal entries 51 | for i=1:6 52 | ik=2*(inodes(i)-1)+icomps(i); it=2*(t(:,inodes(i))-1)+icomps(i); 53 | Rij=B{1,ik}.*E{1,ik}+B{2,ik}.*E{2,ik}+B{3,ik}.*E{3,ik}; 54 | R=R+sparse(it,it,ar.*Rij,nn,nn); 55 | end 56 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas2dvmes.m: -------------------------------------------------------------------------------- 1 | function S=kelas2dvmes(p,t,u,E,nu) 2 | %KELAS2DVMES Computes 2D Von Mises effective stress 3 | %-------------------------------------------------------------------- 4 | % S=kelas2dvmes(p,t,u,E,nu) 5 | % 6 | % Input: 7 | % p : node coodinates, np∗2 8 | % t : triangle vertices, nt∗3 9 | % u : displacements field, (2*np)*1 10 | % E,nu : Young modulus and Poisson ratio 11 | % S : Von Mises effective stress, np*1 12 | %-------------------------------------------------------------------- 13 | % (c) J. Koko, LIMOS 2006-2015, koko@isima.fr 14 | %-------------------------------------------------------------------- 15 | np=size(p,1); nn=2*np; lam=E*nu/((1+nu)*(1-2*nu)); mu=E/(2*(1+nu)); 16 | it1=t(:,1); it2=t(:,2); it3=t(:,3); 17 | % elements area and gradient of basis functions 18 | [ar,phi1,phi2,phi3]=kpde2dgphi(p,t); 19 | % strain 20 | u1=u(1:2:end); u2=u(2:2:end); 21 | uh=[u1(it1) u1(it2) u1(it3)]; vh=[u2(it1) u2(it2) u2(it3)]; 22 | e11=uh(:,1).*phi1(:,1)+uh(:,2).*phi2(:,1)+uh(:,3).*phi3(:,1); 23 | e22=vh(:,1).*phi1(:,2)+vh(:,2).*phi2(:,2)+vh(:,3).*phi3(:,2); 24 | e12=uh(:,1).*phi1(:,2)+uh(:,2).*phi2(:,2)+uh(:,3).*phi3(:,2)... 25 | +vh(:,1).*phi1(:,1)+vh(:,2).*phi2(:,1)+vh(:,3).*phi3(:,1); 26 | sig11=(lam+2*mu)*e11+lam*e22; sig22=lam*e11+(lam+2*mu)*e22; sig12=mu*e12; 27 | clear uh vh e11 e22 e12 28 | % patch 29 | arp=sparse(it1,1,ar,np,1)+sparse(it2,1,ar,np,1)+sparse(it3,1,ar,np,1); 30 | sm1=ar.*sig11; sm2=ar.*sig22; sm12=ar.*sig12; 31 | s1=sparse(it1,1,sm1,np,1)+sparse(it2,1,sm1,np,1)+sparse(it3,1,sm1,np,1); 32 | s2=sparse(it1,1,sm2,np,1)+sparse(it2,1,sm2,np,1)+sparse(it3,1,sm2,np,1); 33 | s12=sparse(it1,1,sm12,np,1)+sparse(it2,1,sm12,np,1)+sparse(it3,1,sm12,np,1); 34 | s1=full(s1./arp); s2=full(s2./arp); s12=full(s12./arp); 35 | % Von mises effective stress 36 | delta=sqrt((s1-s2).^2+4*s12.^2); sp1=s1+s2+delta; sp2=s1+s2-delta; 37 | S=sqrt(sp1.^2+sp2.^2-sp1.*sp2); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas3d_exple1.m: -------------------------------------------------------------------------------- 1 | % 2 | % Linear elasticity 2D/3D 3 | % 4 | % 2D: \Omega=(-5 5)*(0 35) 5 | % f=(0,-.75) 6 | % g=(0,10) 7 | % 3D: \Omega=(-5 5)*(0 35)*(-5 5) 8 | % f=(0,0,-.75) 9 | % g=(0,0,10) 10 | %---------------------------------------------------------- 11 | E=30000; nu=0.4; 12 | d=2; 13 | nx=11; 14 | ny=36; 15 | fx=0; fy=0; fz=-.75; 16 | gx=0; gy=0; gz=10; 17 | 18 | % mesh generation 19 | if (d==2) 20 | ax=-5; bx=5; ay=0; by=35; 21 | [p,t,bpx,bpy]=kpde2dumsh(ax,bx,ay,by,nx,ny); 22 | ibcd=[2*bpy(:,1)-1; 2*bpy(:,1)-1]; 23 | ibn=bpy(:,2); x=p(ibn,1); [~,ix]=sort(x); ibn=ibn(ix); ne=length(ibn); 24 | eneum=[ibn(1:ne-1) ibn(2:ne)]; 25 | ibcn=ibn; 26 | clear bpx bpy ibn x ix 27 | elseif (d==3) 28 | ax=-5; bx=5; ay=0; by=35; az=-5; bz=5; 29 | nz=nx; 30 | [p,t,bpx,bpy,bpz]=kpde3dumsh(ax,bx,ay,by,az,bz,nx,ny,nz); 31 | ibcd=[3*bpy(:,1)-2; 3*bpy(:,1)-1; 3*bpy(:,1)]; 32 | % Neumann condition at y=35 33 | ibn=bpy(:,2); ref=zeros(np,1); ref(ibn)=1; 34 | ref1=ref(t(:,1)); ref2=ref(t(:,2)); ref3=ref(t(:,3)); ref4=ref(t(:,4)); 35 | rr=ref1+ref2+ref3+ref4; 36 | irr=find(rr==3); tn=t(irr,:); 37 | tref=[ref1(irr) ref2(irr) ref3(irr) ref4(irr)]; [~,iref]=sort(tref,2); 38 | tb=zeros(size(tn)); 39 | for i=1:size(tn,1), tb(i,:)=tn(i,iref(i,:)); end 40 | tb(:,1)=[]; 41 | ibcn=union(tb(:,1),union(tb(:,2),tb(:,3))); 42 | clear bpx pby bpz ref1 ref2 ref3 ref4 rr irr tn tref iref tn 43 | else 44 | error('The value of d is not valid') 45 | end 46 | 47 | np=size(p,1); nt=size(t,1); 48 | fprintf('Dimension :%3d\n',d) 49 | fprintf('Number of vertices :%5d\n',np) 50 | fprintf('Number of elements :%5d\n',nt) 51 | fprintf('Number of d.o.f. :%5d\n',d*np) 52 | 53 | 54 | % Right-hand sides 55 | f1=zeros(np,1); 56 | g1=zeros(np,1); g2=g1; 57 | if (d==2) 58 | f2=-fz*ones(np,1); 59 | g2(ibcn)=gz; 60 | else 61 | f2=zeros(np,1); f3=-fz*ones(np,1); 62 | g2=g1; g3=g1; g3(ibcn)=gz; 63 | end 64 | 65 | 66 | % matrices & vecteurs 67 | if (d==2) 68 | R=kelas2d(p,t,E,nu); 69 | f=kelas2drhs(p,t,f1,f2,f3); 70 | g=kelas2drhsn(p,eneum,g1,g2); 71 | else 72 | R=kelas3d(p,t,E,nu); 73 | f=kelas3drhs(p,t,f1,f2,f3,); 74 | g=kelas3drhsn(p,tb,g1,g2); 75 | end 76 | 77 | % Dirichlet conditions (penalization) 78 | R(ibcd,ibcd)=A(ibcd,ibcd)+10^20*speye(length(ibcd)); 79 | b=f+g; b(ibcd)=0; 80 | 81 | % Solution (Gaussian elimination) 82 | ui=A\b; u=zeros(nn,1); u(inodes)=ui; 83 | 84 | % vizualisation 85 | if (d==2) 86 | s=kelas2dvmes(p,t,u,E,nu); 87 | kelas2dshow(p,t,100,s) 88 | else 89 | s=kelas3dvmes(p,t,u,E,nu); 90 | kelas3dshow(p,t,u,100,s) 91 | end 92 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas3drhs.m: -------------------------------------------------------------------------------- 1 | function b=kelas3drhs(p,t,fx,fy,fz) 2 | %KELAS3DRHS Assembles the right-hand side with P1 finite element 3 | %-------------------------------------------------------------------- 4 | % b=kpde3drhs(p,t,fx,fy,fz) 5 | % 6 | % Input: 7 | % p : Nodes coordinates, np*3 8 | % t : Tetrahedron vertices, nt*4 9 | % f : Source term, column vector np*1 10 | % 11 | % Output: 12 | % b : Right-hand side, (3*np)*1 13 | %-------------------------------------------------------------------- 14 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 15 | %-------------------------------------------------------------------- 16 | np=size(p,1); nt=size(t,1); nn=3*np; 17 | it1=t(:,1); it2=t(:,2); it3=t(:,3); it4=t(:,4); 18 | 19 | % f at centers of mass 20 | f1=(fx(it1)+fx(it2)+fx(it3)+fx(it4))/4; 21 | f2=(fy(it1)+fy(it2)+fy(it3)+fy(it4))/4; 22 | f3=(fz(it1)+fz(it2)+fz(it3)+fz(it4))/4; 23 | 24 | % elements volume 25 | vol= kpde3dgphi(p,t); 26 | 27 | % assembly 28 | f=[f1.*vol/4 f2.*vol/4 f3.*vol/4]; 29 | ff=sparse(np,3); 30 | for i=1:4 31 | ff(:,1)=ff(:,1)+sparse(t(:,i),1,f(:,1),np,1); 32 | ff(:,2)=ff(:,2)+sparse(t(:,i),1,f(:,2),np,1); 33 | ff(:,3)=ff(:,3)+sparse(t(:,i),1,f(:,3),np,1); 34 | end 35 | ff=full(ff); b=zeros(nn,1); 36 | b(1:3:nn-2)=ff(:,1); b(2:3:nn-1)=ff(:,2); b(3:3:nn)=ff(:,3); 37 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas3drhsn.m: -------------------------------------------------------------------------------- 1 | function b=kelas3drhsn(p,fneum,g1,g2,g3) 2 | %KPDE3DRHSN Assembles the RHS contribution of Neumann boundary conditions. 3 | %-------------------------------------------------------------------- 4 | % b=kelas3drhsn(p,fneum,g1,g2,g3) 5 | % 6 | % input: 7 | % p : Nodes coordinates, np*3 8 | % fneum : Boundary faces (triangles), nf*3 9 | % g1,g2,g3 : Neumann boundary condition,column vectors np*1 10 | % g ~=0 on Neumann nodes 11 | % 12 | % Output: 13 | % b : Right-hand side, np*1 14 | %-------------------------------------------------------------------- 15 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 16 | %-------------------------------------------------------------------- 17 | np=size(p,1); nt=size(fneum,1); 18 | 19 | % faces area 20 | it1=fneum(:,1); it2=fneum(:,2); it3=fneum(:,3); 21 | v1=p(it2,:)-p(it1,:); v2=p(it3,:)-p(it1,:); 22 | v=cross(v1,v2,2); ar=sqrt(sum(v.*v,2))/2; 23 | 24 | % g at centers of mass 25 | gh1=ar.*(g1(it1)+g1(it2)+g1(it3))/9; 26 | gh2=ar.*(g2(it1)+g2(it2)+g2(it3))/9; 27 | gh3=ar.*(g3(it1)+g3(it2)+g3(it3))/9; 28 | 29 | % assembly 30 | gg1=sparse(it1,1,gh1,np,1)+sparse(it2,1,gh1,np,1)+sparse(it3,1,gh1,np,1); 31 | gg2=sparse(it1,1,gh2,np,1)+sparse(it2,1,gh2,np,1)+sparse(it3,1,gh2,np,1); 32 | gg3=sparse(it1,1,gh3,np,1)+sparse(it2,1,gh3,np,1)+sparse(it3,1,gh3,np,1); 33 | b=zeros(3*np,1); 34 | b(1:3:3*np-2)=full(gg1); b(2:3:3*np-1)=full(gg2); b(3:3:3*np)=full(gg3); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas3dshow.m: -------------------------------------------------------------------------------- 1 | function kelas3dshow(p,t,u,mag,sf) 2 | %KELAS3DSHOW 3D linear elasticity visualization 3 | %-------------------------------------------------------------------- 4 | % kelas3dshow(p,t,u,mag) - deformed mesh 5 | % kelas3dshow(p,t,u,mag,sf) - deformed mesh + sf 6 | % 7 | % Input: 8 | % p : node coordinates, np*3 9 | % t : tetrahedron vertices, nt*4 10 | % u : Displacements vector, (3*np)*1 11 | % mag : Magnification factor, positive sclar 12 | % s : Variable to be visualized (e.g. shear energy density), np*1 13 | % 14 | %-------------------------------------------------------------------- 15 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 16 | %-------------------------------------------------------------------- 17 | np=size(p,1); pu=zeros(np,3); 18 | pu(:,1)=p(:,1)+mag*u(1:3:end); 19 | pu(:,2)=p(:,2)+mag*u(2:3:end); 20 | pu(:,3)=p(:,3)+mag*u(3:3:end); 21 | 22 | if (nargin==4) 23 | kpde3dshow(pu,t,zeros(np,1)); % deformed mesh 24 | axis on 25 | else 26 | kpde3dshow(pu,t,sf); % deformed mesh + stress 27 | axis on, colorbar('South') 28 | end -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas3dstf.m: -------------------------------------------------------------------------------- 1 | function R=kelas3dstf(p,t,Young,nu) 2 | %KELAS3DSTF Assembles the stiffness matrix for 3D linear elasticity 3 | % with P1 finite element 4 | %-------------------------------------------------------------------- 5 | % R=kelas3dstf(p,t,Young,nu) 6 | % 7 | % Input: 8 | % p : Nodes coordinates, np*3 9 | % t : Tetrahedron vertices, nt*4 10 | % Young : Young modulus (scalar) 11 | % nu : Poisson ratio (scalar) 12 | % 13 | % Output: 14 | % R : Stiffness matrix, sparse (3*np)*(3*np) 15 | % symmetric, positive semidefinite 16 | %-------------------------------------------------------------------- 17 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 18 | %-------------------------------------------------------------------- 19 | np=size(p,1); nn=3*np; nt=size(t,1); 20 | mu=.5*Young/(1+nu); lam=Young*nu/((1+nu)*(1-2*nu)); 21 | C=zeros(6);C(1:3,1:3)=[lam+mu lam lam; 22 | lam lam+mu lam; 23 | lam lam lam+mu]; C=C+mu*eye(6); 24 | % gradients of basis functions 25 | [vol,g1,g2,g3,g4] = kpde3dgphi(p,t); 26 | B=cell(6,12); [B{:,:}]=deal(sparse(nt,1)); 27 | B(1,1:3:10)={g1(:,1) g2(:,1) g3(:,1) g4(:,1)}; 28 | B(2,2:3:11)={g1(:,2) g2(:,2) g3(:,2) g4(:,2)}; 29 | B(3,3:3:12)={g1(:,3) g2(:,3) g3(:,3) g4(:,3)}; 30 | B(4,1:3:10)={g1(:,2) g2(:,2) g3(:,2) g4(:,2)}; 31 | B(4,2:3:11)={g1(:,1) g2(:,1) g3(:,1) g4(:,1)}; 32 | B(5,1:3:10)={g1(:,3) g2(:,3) g3(:,3) g4(:,3)}; 33 | B(5,3:3:12)={g1(:,1) g2(:,1) g3(:,1) g4(:,1)}; 34 | B(6,2:3:11)={g1(:,3) g2(:,3) g3(:,3) g4(:,3)}; 35 | B(6,3:3:12)={g1(:,2) g2(:,2) g3(:,2) g4(:,2)}; 36 | E=cell(6,12); % E=C*B 37 | for i=1:6 38 | for j=1:12 39 | E{i,j}=C(i,1)*B{1,j}+C(i,2)*B{2,j}+C(i,3)*B{3,j}... 40 | +C(i,4)*B{4,j}+C(i,5)*B{5,j}+C(i,6)*B{6,j}; 41 | end 42 | end 43 | inodes=[1 1 1 2 2 2 3 3 3 4 4 4]; icomps=[1 2 3 1 2 3 1 2 3 1 2 3]; 44 | R=sparse(nn,nn); 45 | % under-diagonal entries 46 | for i=1:12 47 | ik=3*(inodes(i)-1)+icomps(i); it=3*(t(:,inodes(i))-1)+icomps(i); 48 | for j=1:i-1 49 | jl=3*(inodes(j)-1)+icomps(j); jt=3*(t(:,inodes(j))-1)+icomps(j); 50 | Rij=B{1,ik}.*E{1,jl}+B{2,ik}.*E{2,jl}+B{3,ik}.*E{3,jl}... 51 | +B{4,ik}.*E{4,jl}+B{5,ik}.*E{5,jl}+B{6,ik}.*E{6,jl}; 52 | R=R+sparse(it,jt,vol.*Rij,nn,nn); 53 | end 54 | end 55 | % transpose 56 | R=R+R.'; 57 | % transpose 58 | for i=1:12 % diagonal entries 59 | ik=3*(inodes(i)-1)+icomps(i); it=3*(t(:,inodes(i))-1)+icomps(i); 60 | Rij=B{1,ik}.*E{1,ik}+B{2,ik}.*E{2,ik}+B{3,ik}.*E{3,ik}... 61 | +B{4,ik}.*E{4,ik}+B{5,ik}.*E{5,ik}+B{6,ik}.*E{6,ik}; 62 | R=R+sparse(it,it,vol.*Rij,nn,nn); 63 | end 64 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kelas3dvmes.m: -------------------------------------------------------------------------------- 1 | function S=kelas3dvmes(p,t,u,E,nu) 2 | %KELAS3DVMES Computes 3D Von Mises effective stress 3 | %-------------------------------------------------------------------- 4 | % S=kelas3dvmes(p,t,u,E,nu) 5 | % 6 | % Input: 7 | % p : node coodinate, np∗3 8 | % t : tetrahedron vertices, nt∗4 9 | % u : displacements field, (3*np)*1 10 | % E,nu : Young modulus and Poisson ratio 11 | % S : Von Mises effective stress, np*1 12 | %-------------------------------------------------------------------- 13 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 14 | %-------------------------------------------------------------------- 15 | np=size(p,1); nn=3*np; lam=E*nu/((1+nu)*(1-2*nu)); mu=E/(2*(1+nu)); 16 | C=zeros(6); C(1:3,1:3)=[lam+mu lam lam; lam lam+mu lam;lam lam lam+mu]; 17 | C=C+mu*eye(6); 18 | % elements volume and gradient of basis functions 19 | [vol,g1,g2,g3,g4]=kpde3dgphi(p,t); 20 | % deformations 21 | it1=t(:,1); it2=t(:,2); it3=t(:,3); it4=t(:,4); 22 | u1=u(1:3:nn-2); u2=u(2:3:nn-1); u3=u(3:3:nn); 23 | e11=u1(it1).*g1(:,1)+u1(it2).*g2(:,1)+u1(it3).*g3(:,1)+u1(it4).*g4(:,1); 24 | e22=u2(it1).*g1(:,2)+u2(it2).*g2(:,2)+u2(it3).*g3(:,2)+u2(it4).*g4(:,2); 25 | e33=u3(it1).*g1(:,3)+u3(it2).*g2(:,3)+u3(it3).*g3(:,3)+u3(it4).*g4(:,3); 26 | e12=u1(it1).*g1(:,2)+u1(it2).*g2(:,2)+u1(it3).*g3(:,2)+u1(it4).*g4(:,2)... 27 | +u2(it1).*g1(:,1)+u2(it2).*g2(:,1)+u2(it3).*g3(:,1)+u2(it4).*g4(:,1); 28 | e13=u1(it1).*g1(:,3)+u1(it2).*g2(:,3)+u1(it3).*g3(:,3)+u1(it4).*g4(:,3)... 29 | +u3(it1).*g1(:,1)+u3(it2).*g2(:,1)+u3(it3).*g3(:,1)+u3(it4).*g4(:,1); 30 | e23=u2(it1).*g1(:,3)+u2(it2).*g2(:,3)+u2(it3).*g3(:,3)+u2(it4).*g4(:,3)... 31 | +u3(it1).*g1(:,2)+u3(it2).*g2(:,2)+u3(it3).*g3(:,2)+u3(it4).*g4(:,2); 32 | % stress 33 | s=cell(6,1); s{4}=mu*vol.*e12; s{5}=mu*vol.*e13; s{6}=mu*vol.*e23; 34 | for i=1:3 35 | s{i}=vol.*(C(i,1)*e11+C(i,2)*e22+C(i,3)*e33); 36 | end 37 | clear e11 e22 e33 e13 e23 e12 38 | % patch 39 | volp=sparse(it1,1,vol,np,1)+sparse(it2,1,vol,np,1)... 40 | +sparse(it3,1,vol,np,1)+sparse(it4,1,vol,np,1); 41 | % average stress 42 | for i=1:6 43 | sm{i}=sparse(it1,1,s{i},np,1)+sparse(it2,1,s{i},np,1)... 44 | +sparse(it3,1,s{i},np,1)+sparse(it4,1,s{i},np,1); 45 | sm{i}=full(sm{i}./volp); 46 | end 47 | % Von Mises effective stress 48 | I1=sm{1}+sm{2}+sm{3}; 49 | I2=sm{1}.*sm{2}+sm{2}.*sm{3}+sm{3}.*sm{1}-sm{4}.^2-sm{5}.^2-sm{6}.^2; 50 | S=full(sqrt(I1.^2-3*I2)); 51 | 52 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde2dgphi.m: -------------------------------------------------------------------------------- 1 | function [ar,g1,g2,g3]=kpde2dgphi(p,t) 2 | %KPDE2DGPHI Elements area and gradient of basis functions 3 | %-------------------------------------------------------------------- 4 | % ar=kpde2dgphi(p,t) 5 | % [ar,g1,g2,g3]=kpde2dgphi(p,t) 6 | % 7 | % Input: 8 | % p : Node coordinates, np*2 9 | % t : Triangle vertices, nt*3 10 | % 11 | % Output: 12 | % ar : elements area, nt*1 13 | % g1,g2,g3 : gradient of basis functions, nt*2 14 | %-------------------------------------------------------------------- 15 | % (c) J. Koko, LIMOS 2006-2015, koko@isima.fr 16 | %-------------------------------------------------------------------- 17 | np=size(p,1); nt=size(t,1); 18 | x21=p(t(:,2),1)-p(t(:,1),1); y21=p(t(:,2),2)-p(t(:,1),2); 19 | x32=p(t(:,3),1)-p(t(:,2),1); y32=p(t(:,3),2)-p(t(:,2),2); 20 | x31=p(t(:,3),1)-p(t(:,1),1); y31=p(t(:,3),2)-p(t(:,1),2); 21 | % triangles area 22 | ar=(x21.*y31-y21.*x31)/2; 23 | if (nargout==1), return; end 24 | % gradients of basis functions 25 | g1=.5*[-y32./ar x32./ar]; g2=.5*[y31./ar -x31./ar]; g3=.5*[-y21./ar x21./ar]; 26 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde2dmss.m: -------------------------------------------------------------------------------- 1 | function M=kpde2dmss(p,t,alfa) 2 | %KPDE2DMSS Assembles the mass matrix with P1 finite element 3 | %-------------------------------------------------------------------- 4 | % M=kpde2dmss(p,t,alfa) 5 | % 6 | % Input: 7 | % p : Node coordinates, np*2 8 | % t : Triangle vertices, nt*3 9 | % alfa : scalar or column vector 10 | % If length(alfa)=np, alfa is defined on nodes 11 | % If length(alfa)=nt, alfa is defined on triangles 12 | % 13 | % Output: 14 | % M : mass matrix (symmetric positive definite) 15 | % sparse np*np 16 | %-------------------------------------------------------------------- 17 | % (c) J. Koko, LIMOS 2006-2015, koko@isima.fr 18 | %-------------------------------------------------------------------- 19 | np=size(p,1); nt=size(t,1); [m1,m2]=size(alfa); 20 | if (m1==1 || m1==nt) 21 | c=alfa; 22 | else 23 | c=(alfa(t(:,1))+alfa(t(:,2))+alfa(t(:,3)))/3; 24 | end 25 | ar=kpde2dgphi(p,t); c=c.*ar/12; 26 | M=sparse(np,np); 27 | % under-diagonal entries 28 | for i=1:3 29 | for j=1:i-1 30 | M=M+sparse(t(:,i),t(:,j),c,np,np); 31 | end 32 | end 33 | M=M+M.'; 34 | % diagonal entries 35 | for i=1:3 36 | M=M+sparse(t(:,i),t(:,i),2*c,np,np); 37 | end 38 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde2drhs.m: -------------------------------------------------------------------------------- 1 | function b=kpde2drhs(p,t,f) 2 | %KPDE2DRHS Assembles the right-hand side with P1 finite element 3 | %-------------------------------------------------------------------- 4 | % b=kpde2drhs(p,t,f) 5 | % 6 | % Input: 7 | % p : Nodes coordinates, np*2 8 | % t : Triangle vertices, nt*3 9 | % f : Source term, column vector np*1 or nt*1 10 | % If length(f)=np, f is defined on nodes 11 | % If length(f)=nt, f is defined on triangles 12 | % 13 | % Output: 14 | % b : Right-hand side, np*1 15 | %-------------------------------------------------------------------- 16 | % (c) J. Koko, LIMOS 2006-2015, koko@isima.fr 17 | %-------------------------------------------------------------------- 18 | np=size(p,1); nt=size(t,1); [m1,m2]=size(f); 19 | if (m1==1 || m1==nt) 20 | ff=f; 21 | else 22 | ff=(f(t(:,1))+f(t(:,2))+f(t(:,3)))/3; 23 | end 24 | ar=kpde2dgphi(p,t); ff=ff.*ar/3; 25 | b=sparse(np,1); 26 | for i=1:3 27 | b=b+sparse(t(:,i),1,ff,np,1); 28 | end 29 | b=full(b); 30 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde2drhsn.m: -------------------------------------------------------------------------------- 1 | function b=kpde2drhsn(p,eneum,g) 2 | %KPDE2DRHSN Assembles the RHS contribution of Neumann boundary conditions. 3 | %-------------------------------------------------------------------- 4 | % b=edp2drhsn(p,eneum,g) 5 | % 6 | % input: 7 | % p : Nodes coordinates, np*2 8 | % eneum : Boundary edges, ne*2 9 | % g : Neumann boundary condition, np*1 10 | % g ~=0 on Neumann nodes 11 | % 12 | % Output: 13 | % b : Right-hand side, np*1 14 | %-------------------------------------------------------------------- 15 | % (c) J. Koko, LIMOS 2006-2015, koko@isima.fr 16 | %-------------------------------------------------------------------- 17 | np=size(p,1); ie1=eneum(:,1); ie2=eneum(:,2); 18 | % segments length 19 | xy=p(ie2,:)-p(ie1,:); ee=sqrt(sum(xy.^2,2)); 20 | gg=ee.*(g(ie1)+g(ie2))/2; 21 | b=sparse(ie1,1,gg,np,1)+sparse(ie2,1,gg,np,1); 22 | b=full(b); 23 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde2dstf.m: -------------------------------------------------------------------------------- 1 | function R=kpde2dstf(p,t,nu) 2 | %KPDE2DSTF Assembles the stiffness matrix with P1 finite element 3 | %-------------------------------------------------------------------- 4 | % R=kpde2dstf(p,t,nu) 5 | % 6 | % Input: 7 | % p : Node coordinates, np*2 8 | % t : Triangle vertices, nt*3 9 | % nu : scalar or column vector 10 | % If length(nu)=np, nu is defined on nodes 11 | % If length(nu)=nt, nu is defined on triangles 12 | % 13 | % Output: 14 | % R : Stiffness matrix (symmetric positive semidefinite) 15 | % sparse np*np 16 | %-------------------------------------------------------------------- 17 | % (c) J. Koko, LIMOS 2006-2015, koko@isima.fr 18 | %-------------------------------------------------------------------- 19 | np=size(p,1); nt=size(t,1); [m1,m2]=size(nu); 20 | if (m1==1 || m1==nt) 21 | c=nu; 22 | else 23 | c=(nu(t(:,1))+nu(t(:,2))+nu(t(:,3)))/3; 24 | end 25 | [ar,g1,g2,g3]=kpde2dgphi(p,t); c=c.*ar; 26 | % cell-array of gradients 27 | g={g1 g2 g3}; 28 | R=sparse(np,np); 29 | % under-diagonal entries 30 | for i=1:3 31 | for j=1:i-1 32 | R=R+sparse(t(:,i),t(:,j),c.*sum(g{i}.*g{j},2),np,np); 33 | end 34 | end 35 | R=R+R.'; 36 | % diagonal entries 37 | for i=1:3 38 | R=R+sparse(t(:,i),t(:,i),c.*sum(g{i}.*g{i},2),np,np); 39 | end 40 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde2dumsh.m: -------------------------------------------------------------------------------- 1 | function [p,t,bpx,bpy]=kpde2dumsh(ax,bx,ay,by,nx,ny) 2 | %KPDE2DUMSH Uniform mesh generation of (ax,bx)*(ay,by) 3 | %-------------------------------------------------------------------- 4 | % [p,t,bpx,bpy]=kpde2dumsh(ax,bx,ay,by,nx,ny) 5 | % 6 | % Inputs: 7 | % (ax,bx) : x-interval 8 | % (ay,by) : y-interval 9 | % nx,ny : number of points in x and y 10 | % 11 | % Ouputs: 12 | % p : nodes coordinates, array np*2 13 | % t : triangle vertices, array nt*3 14 | % bpx,bpy : boundary nodes, arrays nx*2 and ny*2 15 | % bpx(:,1), bpx(:,2), bundary nodes at y=ay and y=by 16 | % bpy(:,1), bpy(:,2), boundary nodes at x=ax and x=bx 17 | %-------------------------------------------------------------------- 18 | np=nx*ny; nq=(nx-1)*(ny-1); nt=2*nq; 19 | 20 | % vertce coordinates 21 | hx=(bx-ax)/(nx-1); hy=(by-ay)/(ny-1); 22 | [x,y]=ndgrid(ax:hx:bx,ay:hy:by); 23 | p=[x(:),y(:)]; 24 | 25 | % quadrangles 26 | ip=[1:nx*ny]'; 27 | ib1=[1:nx]'; ib2=nx*[1:ny]'; 28 | ib3=[nx*(ny-1)+1:nx*ny]'; ib4=[1:nx:nx*ny]'; 29 | ib23=union(ib2,ib3); ib34=union(ib3,ib4); 30 | ib14=union(ib1,ib4); ib12=union(ib1,ib2); 31 | iq1=setdiff(ip,ib23); iq2=setdiff(ip,ib34); 32 | iq3=setdiff(ip,ib14); iq4=setdiff(ip,ib12); 33 | 34 | % triangulation 35 | t=zeros(nt,3); 36 | t(1:nq,1)=iq1; t(1:nq,2)=iq2; t(1:nq,3)=iq3; 37 | t(nq+1:2*nq,1)=iq3; t(nq+1:2*nq,2)=iq4; t(nq+1:2*nq,3)=iq1; 38 | 39 | % boundary nodes 40 | bpx=[ib1 ib3]; 41 | bpy=[ib4 ib2]; -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde3dgphi.m: -------------------------------------------------------------------------------- 1 | function [vol,g1,g2,g3,g4]=kpde3dgphi(p,t) 2 | %KPDE3DGPHI Elenemts volume and gradient of basis functions 3 | %-------------------------------------------------------------------- 4 | % vol=kpde3dgphi(p,t) 5 | % [vol,g1,g2,g3]=kpde3dgphi(p,t) 6 | % 7 | % Input: 8 | % p : Node coordinates, np*3 9 | % t : Tetrahedron vertices, nt*4 10 | % 11 | % Output: 12 | % vol : elements volume, nt*1 13 | % g1,g2,g3,g4 : gradient of basis functions, nt*3 14 | %-------------------------------------------------------------------- 15 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 16 | %-------------------------------------------------------------------- 17 | it1=t(:,1); it2=t(:,2); it3=t(:,3); it4=t(:,4); 18 | x1=p(it1,1); x2=p(it2,1); x3=p(it3,1); x4=p(it4,1); 19 | y1=p(it1,2); y2=p(it2,2); y3=p(it3,2); y4=p(it4,2); 20 | z1=p(it1,3); z2=p(it2,3); z3=p(it3,3); z4=p(it4,3); 21 | % 3x3 Jacobian matrix & determinant 22 | J11=x2-x1; J12=y2-y1; J13=z2-z1; 23 | J21=x3-x1; J22=y3-y1; J23=z3-z1; 24 | J31=x4-x1; J32=y4-y1; J33=z4-z1; 25 | det=J11.*(J22.*J33-J32.*J23)+J12.*(J31.*J23-J21.*J33)+J13.*(J21.*J32-J31.*J22); 26 | % elements volume 27 | vol=abs(det)/6; 28 | if (nargout == 1), return; end 29 | % Jacobian inverse C 30 | C11=(J22.*J33-J32.*J23)./det; C12=(J13.*J32-J12.*J33)./det; C13=(J12.*J23-J13.*J22)./det; 31 | C21=(J31.*J23-J21.*J33)./det; C22=(J11.*J33-J13.*J31)./det; C23=(J21.*J13-J23.*J11)./det; 32 | C31=(J21.*J32-J31.*J22)./det; C32=(J12.*J31-J32.*J11)./det; C33=(J11.*J22-J12.*J21)./det; 33 | % gradients of basis functions 34 | g2=[C11 C21 C31]; g3=[C12 C22 C32]; g4=[C13 C23 C33]; g1=-g2-g3-g4; 35 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde3dmss.m: -------------------------------------------------------------------------------- 1 | function M=kpde3dmss(p,t,alfa) 2 | %KPDE3DMSS Assembles the mass matrix with P1 finite element 3 | %-------------------------------------------------------------------- 4 | % M=kpde3dmss(p,t,alfa) 5 | % 6 | % Input: 7 | % p : Node coordinates, np*3 8 | % t : Tetrahedron vertices, nt*4 9 | % alfa : scalar or column vector 10 | % If length(alfa)=np, alfa is defined on nodes 11 | % If length(alfa)=nt, alfa is defined on tetrahedra 12 | % 13 | % Output: 14 | % M : Mass matrix (symmetric positive definite) 15 | % sparse np*np 16 | %-------------------------------------------------------------------- 17 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 18 | %-------------------------------------------------------------------- 19 | np=size(p,1); nt=size(t,1); [m1,m2]=size(alfa); 20 | if (m1==1 || m1==nt) 21 | c=alfa; 22 | else 23 | c=(alfa(t(:,1))+alfa(t(:,2))+alfa(t(:,3))+alfa(t(:,4)))/4; 24 | end 25 | % elements area 26 | vol=kpde3dgphi(p,t); c=c.*vol/20; 27 | M=sparse(np,np); 28 | % under-diagonal entries 29 | for i=1:4 30 | for j=1:i-1 31 | M=M+sparse(t(:,i),t(:,j),c,np,np); 32 | end 33 | end 34 | % transpose 35 | M=M+M.'; 36 | % diagonal entries 37 | for i=1:4 38 | M=M+sparse(t(:,i),t(:,i),2*c,np,np); 39 | end 40 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde3drhs.m: -------------------------------------------------------------------------------- 1 | function b=kpde3drhs(p,t,f) 2 | %KPDE3DRHS Assembles the right-hand side with P1 finite element 3 | %-------------------------------------------------------------------- 4 | % b=kpde3drhs(p,t,f) 5 | % 6 | % Input: 7 | % p : Nodes coordinates, np*3 8 | % t : Tetrahedron vertices, nt*4 9 | % f : Source term, column vector np*1 or nt*1 10 | % If length(f)=np, f is defined on nodes 11 | % If length(f)=nt, f is defined on tetrahedra 12 | % 13 | % Output: 14 | % b : Right-hand side, np*1 15 | %-------------------------------------------------------------------- 16 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 17 | %-------------------------------------------------------------------- 18 | 19 | np=size(p,1); nt=size(t,1); [m1,m2]=size(f); 20 | if ( m1==1 || m1==nt ) 21 | ff=f ; 22 | else 23 | ff=(f(t(:,1))+f(t(:,2))+f(t(:,3))+f(t(:,4)))/4; 24 | end 25 | vol=kpde3dgphi(p,t); ff=ff.*vol/4; 26 | b=sparse(np,1); 27 | for i=1:4 28 | b=b+sparse(t(:,i),1,ff,np,1); 29 | end 30 | b=full(b); 31 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde3drhsn.m: -------------------------------------------------------------------------------- 1 | function gh=kpde3drhsn(p,fneum,g) 2 | %KPDE3DRHSN Assembles the RHS contribution of Neumann boundary conditions. 3 | %-------------------------------------------------------------------- 4 | % b=edp3drhsn(p,fneum,g) 5 | % 6 | % input: 7 | % p : Nodes coordinates, np*3 8 | % fneum : Boundary faces (triangles), nf*3 9 | % g : Neumann boundary condition, np*1 10 | % g ~=0 on Neumann nodes 11 | % 12 | % Output: 13 | % b : Right-hand side, np*1 14 | %-------------------------------------------------------------------- 15 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 16 | %-------------------------------------------------------------------- 17 | %-------------------------------------------------------------------- 18 | np=size(p,1); it1=fneum(:,1); it2=fneum(:,2); it3=fneum(:,3); 19 | % faces area 20 | v1=p(it2,:)-p(it1,:); v2=p(it3,:)-p(it1,:); v=cros(v1,v2,2); 21 | farea=sqrt(sum(v.*v,2))/2; 22 | gg=farea.*(g(it1)+g(it2)+g(it3))/3; 23 | b=sparse(it1,1,gg,np,1)+sparse(it2,1,gg,np,1)+sparse(it3,1,gg,np,1); 24 | b=full(b); 25 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde3dshow.m: -------------------------------------------------------------------------------- 1 | function []=kpde3dshow(p,t,u,it) 2 | %KPDE3DSHOW KPDE3D Visualization function 3 | %-------------------------------------------------------------------- 4 | % kpde3dshow(p,t,u) 5 | % kpde3dshow(p,t,u,it) 6 | % 7 | % Input: 8 | % p : node coodinate, np∗3 9 | % t : tetrahedron vertices, nt∗4 10 | % u : PDE solution, np*1 11 | % it : set of tetrahedra defining a subdomain of interest 12 | %-------------------------------------------------------------------- 13 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 14 | %-------------------------------------------------------------------- 15 | ii=[1:size(t,1)]'; 16 | if (nargin == 4) 17 | ii=it; 18 | end 19 | % faces of tetrahedra 20 | fh0=[t(ii,[1,2,3]); 21 | t(ii,[1,2,4]); 22 | t(ii,[1,3,4]); 23 | t(ii,[2,3,4])]; 24 | fh=sort(fh0,2); 25 | [~,ie,je]=unique(fh,'rows'); 26 | % boundary faces 27 | f=fh(ie,:); 28 | nf=size(f,1); 29 | hf=accumarray(je,1,[nf 1]); ib=find(hf==1); 30 | tb=f(ib,:); 31 | % visualization with trisurf 32 | trisurf(tb,p(:,1),p(:,2),p(:,3),u,'facecolor','interp'), axis image -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde3dstf.m: -------------------------------------------------------------------------------- 1 | function R=kpde3dstf(p,t,nu) 2 | %KPDE3DSTF Assembles the stiffness matrix with P1 finite element 3 | %-------------------------------------------------------------------- 4 | % R=kpde3dstf(p,t,nu) 5 | % 6 | % Input: 7 | % p : Node coordinates, np*3 8 | % t : Tetrahedron vertices, nt*4 9 | % nu : scalar or column vector 10 | % If length(nu)=np, nu is defined on nodes 11 | % If length(nu)=nt, nu is defined on tetrahedra 12 | % 13 | % Output: 14 | % R : Stiffness matrix (symmetric positive semidefinite) 15 | % sparse np*np 16 | %-------------------------------------------------------------------- 17 | % (c) J. Koko, LIMOS 2015, koko@isima.fr 18 | %-------------------------------------------------------------------- 19 | np=size(p,1); nt=size(t,1); [m1,m2]= size(nu) ; 20 | if (m1==1 || m1==nt) 21 | c=nu ; 22 | else 23 | c=(nu(t(:,1))+nu(t(:,2))+nu(t(:,3))+nu(t(:,4)))/4; 24 | end 25 | % gradients of basis functions 26 | [vol,g1,g2,g3,g4] = kpde3dgphi(p,t); 27 | c=c.*vol; 28 | % cell-array of gradient 29 | g={g1 g2 g3 g4}; 30 | R=sparse(np,np); 31 | % under-diagonal entries 32 | for i=1:4 33 | for j=1:i-1 34 | R=R+sparse(t(:,i),t(:,j),c.*sum(g{i}.*g{j},2),np,np); 35 | end 36 | end 37 | % transpose 38 | R=R+R.'; 39 | % diagonal entries 40 | for i=1:4 41 | R=R+sparse(t(:,i),t(:,i),c.*sum(g{i}.^2,2),np,np); 42 | end 43 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_k/kpde3dumsh.m: -------------------------------------------------------------------------------- 1 | function [p,t,bpx,bpy,bpz]=kpde3dumsh(ax,bx,ay,by,az,bz,nx,ny,nz) 2 | %KPDE3DUMSH Uniform mesh generation of (ax,bx)*(ay,by)*(az,bz) 3 | %-------------------------------------------------------------------- 4 | % [p,t,bpx,bpy,bpz]=kpde3dumsh(ax,bx,ay,by,az,bz,nx,ny,nz) 5 | % 6 | % Input: 7 | % (ax,bx) : x-interval 8 | % (ay,by) : y-interval 9 | % (az,bz) : z-interval 10 | % nx,ny,nz : number of points in x, y and z 11 | % Ouput: 12 | % p : Nodes coordinates, array np*3 13 | % t : Tetrahedron vertices, array nt*4 14 | % bpx,bpy,bpz : boundary nodes, arrays nx*2, ny*2 and nz*2 15 | % bpx(:,1), bpx(:,2) boundary nodes at x=ax and x=bx 16 | % bpy(:,1), bpy(:,2) boundary nodes at y=ay and y=by 17 | % bpz(:,1), bpz(:,2) boundary nodes at z=az and z=bz 18 | %-------------------------------------------------------------------- 19 | np=nx*ny*nz; nq=(nx-1)*(ny-1)*(nz-1); nt=6*nq; 20 | 21 | % nodes coordinates 22 | hx=(bx-ax)/(nx-1); hy=(by-ay)/(ny-1); hz=(bz-az)/(nz-1); 23 | [x,y,z]=ndgrid(ax:hx:bx,ay:hy:by,az:hz:bz); 24 | p=[x(:),y(:),z(:)]; 25 | 26 | % quadrangles 27 | ip=[1:nx*ny*nz]'; ijk=reshape(ip,[nx,ny,nz]); 28 | b1=squeeze(ijk(:,1,:)); ib1=b1(:); 29 | b2=squeeze(ijk(nx,:,:)); ib2=b2(:); 30 | b3=squeeze(ijk(:,ny,:)); ib3=b3(:); 31 | b4=squeeze(ijk(1,:,:)); ib4=b4(:); 32 | b5=squeeze(ijk(:,:,1)); ib5=b5(:); 33 | b6=squeeze(ijk(:,:,nz)); ib6=b6(:); 34 | 35 | ib236=union(ib2,union(ib3,ib6)); ip1=setdiff(ip,ib236); 36 | ib346=union(ib3,union(ib4,ib6)); ip2=setdiff(ip,ib346); 37 | ib345=union(ib3,union(ib4,ib5)); ip3=setdiff(ip,ib345); 38 | ib235=union(ib2,union(ib3,ib5)); ip4=setdiff(ip,ib235); 39 | ib126=union(ib1,union(ib2,ib6)); ip5=setdiff(ip,ib126); 40 | ib146=union(ib1,union(ib4,ib6)); ip6=setdiff(ip,ib146); 41 | ib145=union(ib1,union(ib4,ib5)); ip7=setdiff(ip,ib145); 42 | ib125=union(ib1,union(ib2,ib5)); ip8=setdiff(ip,ib125); 43 | 44 | % triangulation 45 | t=zeros(nt,4); 46 | iq1=1:nq; iq2=iq1+nq; iq3=iq2+nq; 47 | iq4=iq3+nq; iq5=iq4+nq; iq6=iq5+nq; 48 | t(iq1,1)=ip1; t(iq1,2)=ip2; t(iq1,3)=ip6; t(iq1,4)=ip7; 49 | t(iq2,1)=ip1; t(iq2,2)=ip6; t(iq2,3)=ip5; t(iq2,4)=ip7; 50 | t(iq3,1)=ip1; t(iq3,2)=ip2; t(iq3,3)=ip7; t(iq3,4)=ip3; 51 | t(iq4,1)=ip1; t(iq4,2)=ip4; t(iq4,3)=ip3; t(iq4,4)=ip7; 52 | t(iq5,1)=ip1; t(iq5,2)=ip5; t(iq5,3)=ip8; t(iq5,4)=ip7; 53 | t(iq6,1)=ip1; t(iq6,2)=ip4; t(iq6,3)=ip7; t(iq6,4)=ip8; 54 | 55 | % boundary nodes 56 | bpx=[ib4 ib2]; bpy=[ib1 ib3]; bpz=[ib5 ib6]; 57 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/deleteRepeatedRows.m: -------------------------------------------------------------------------------- 1 | function [matrix,I]=deleteRepeatedRows(matrix) 2 | %function: [element2edges, edge2nodes]=edge_numbering(elements) 3 | %requires: deleterepeatedrows 4 | %generates edges of (triangular) triangulation defined in elements 5 | %elements is matrix, whose rows contain numbers of its element nodes 6 | %element2edges returns edges numbers of each triangular element 7 | %edge2nodes returns two node numbers of each edge 8 | %example: [element2edges, edge2nodes]=edge_numbering([1 2 3; 2 4 3]) 9 | 10 | 11 | %fast and short way suggested by John D'Ericco working in both 2D and 3D 12 | matrixs=sort(matrix,2); 13 | [dummy,J,I] = unique(matrixs,'rows'); 14 | %I=reshape(I,size(matrixs,2),size(I,1)/size(matrixs,2)); 15 | matrix=matrix(J,:); 16 | 17 | %original code working only in 2D 18 | % [matrixs,tags] = sortrows(sort(matrix,2)); 19 | % 20 | % % which ones were reps? 21 | % k = find(all(diff(matrixs)==0,2)); 22 | % 23 | % %these rows of matrix are repeated 24 | % repeated=tags(k); 25 | % 26 | % %and these rows will be removed 27 | % removed=tags(k+1); 28 | % 29 | % %both lists are sorted 30 | % [removeds, tags2]=sort(removed); 31 | % repeateds=repeated(tags2); 32 | % 33 | % % delete the tags to removed rows 34 | % tags(k+1) = []; 35 | % % and recover the original array, in the original order. 36 | % matrix = matrix(sort(tags),:); 37 | % 38 | % %row indices before matrix compression indicating repetition 39 | % I=insertvector((1:size(matrix,1))',repeateds,removeds); 40 | % 41 | % %------------------------------------------------------------- 42 | % function r=insertvector(v,pos_from,pos_to) 43 | % tf=false(1,numel(v)+numel(pos_to)); 44 | % r=double(tf); 45 | % tf(pos_to)=true; 46 | % r(~tf)=v; 47 | % r(tf)=r(pos_from); 48 | % %------------------------------------------------------------- 49 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/entryInWhichRows.m: -------------------------------------------------------------------------------- 1 | function entryrows=entryInWhichRows(A) 2 | %function: entryrows=entryInWhichRows(A) 3 | %requires: none 4 | %for every entry of integer matrix A, 5 | %its rows indices are stored in output matrix, 6 | %zeros entries indicate no more occurence 7 | %example: entryrows=entryInWhichRows([1 2; 1 3; 2 2]) returns 8 | % entryrows=[1 2 0; 9 | % 1 3 3; 10 | % 2 0 0] 11 | %meaning: entry 1 appears in rows 1 and 2 12 | % entry 2 appears in rows 1 and 3 (twice) 13 | % entry 3 appears in row 2 only 14 | 15 | %size computation; 16 | r=max(max(A)); 17 | repetition=accumarray(A(:),ones(numel(A),1)); 18 | c=max(repetition); 19 | 20 | %filling rows occurences 21 | %this part should be somehow vectorized! 22 | entryrows=zeros(r,c); 23 | repetition=zeros(r,1); 24 | for i=1:size(A,1) 25 | for j=1:size(A,2) 26 | index=A(i,j); 27 | repetition(index)=repetition(index)+1; 28 | entryrows(index,repetition(index))=i; 29 | end 30 | end -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/getEdges.m: -------------------------------------------------------------------------------- 1 | function [edge2nodes, edge2elems, elems2edges, node2edges]=getEdges(elems2nodes) 2 | %works only on 2D triangular and 3D tetrahedral meshes! 3 | %function: [element2edges, edge2nodes]=edge_numbering(elements) 4 | %requires: deleterepeatedrows 5 | %generates edges of (triangular) triangulation defined in elements 6 | %elements is matrix, whose rows contain numbers of its element nodes 7 | %element2edges returns edges numbers of each triangular element 8 | %edge2nodes returns two node numbers of each edge 9 | %example in 2D: [element2edges, edge2nodes]=getEdges([1 2 3; 2 4 3]) 10 | %example in 3D: [element2edges, edge2nodes]=getEdges([1 2 3 4; 1 2 3 5; 1 2 4 6]) 11 | 12 | %2D case 13 | if (size(elems2nodes,2)==3) 14 | %extracts sets of edges 15 | edges1=elems2nodes(:,[2 3]); 16 | edges2=elems2nodes(:,[3 1]); 17 | edges3=elems2nodes(:,[1 2]); 18 | 19 | %as sets of their nodes (vertices) 20 | vertices=zeros(size(elems2nodes,1)*3,2); 21 | vertices(1:3:end,:)=edges1; 22 | vertices(2:3:end,:)=edges2; 23 | vertices(3:3:end,:)=edges3; 24 | 25 | %repeated sets of nodes (joint edges) are eliminated 26 | [edge2nodes,elems2edges]=deleteRepeatedRows(vertices); 27 | elems2edges=reshape(elems2edges,3,size(elems2nodes,1))'; 28 | end 29 | 30 | %3D case 31 | if (size(elems2nodes,2)==4) 32 | %extracts sets of edges 33 | edges1=elems2nodes(:,[1 2]); 34 | edges2=elems2nodes(:,[1 3]); 35 | edges3=elems2nodes(:,[1 4]); 36 | edges4=elems2nodes(:,[2 3]); 37 | edges5=elems2nodes(:,[2 4]); 38 | edges6=elems2nodes(:,[3 4]); 39 | 40 | %as sets of their nodes (vertices) 41 | vertices=zeros(size(elems2nodes,1)*6,2); 42 | vertices(1:6:end,:)=edges1; 43 | vertices(2:6:end,:)=edges2; 44 | vertices(3:6:end,:)=edges3; 45 | vertices(4:6:end,:)=edges4; 46 | vertices(5:6:end,:)=edges5; 47 | vertices(6:6:end,:)=edges6; 48 | 49 | %repeated sets of nodes (joint edges) are eliminated 50 | [edge2nodes,elems2edges]=deleteRepeatedRows(vertices); 51 | elems2edges=reshape(elems2edges,6,size(elems2nodes,1))'; 52 | end 53 | 54 | %add on 55 | edge2elems=entryInWhichRows(elems2edges); 56 | if (size(edge2elems,2)==1) 57 | edge2elems=[edge2elems 0*edge2elems]; %all edges are boundary edges!!! 58 | end 59 | node2edges=entryInWhichRows(edge2nodes); 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/get_boundary_edges.m: -------------------------------------------------------------------------------- 1 | function bedges2edges = get_boundary_edges(edges2nodes,bedges2nodes) 2 | 3 | % GETBOUNDARYEDGES 4 | % Calculates boundary edges for 2D and 3D meshes. This is needed for 5 | % setting boundary conditions for the eddy current problem. 6 | % 7 | % IN: edges2nodes edges by their nodes 8 | % bedges2nodes boundary edges/faces by their nodes in 2D/3D 9 | % 10 | % OUT: bedges2edges boundary edge indexes to 'edges2nodes' 11 | % 12 | 13 | dim = size(bedges2nodes,2); 14 | 15 | if ( dim == 3 ) 16 | %extracts sets of edges 17 | edges1 = bedges2nodes(:,[1 2]); 18 | edges2 = bedges2nodes(:,[2 3]); 19 | edges3 = bedges2nodes(:,[3 1]); 20 | 21 | %as sets of their nodes (vertices) 22 | vertices = zeros(size(bedges2nodes,1)*3,2); 23 | vertices(1:3:end,:) = edges1; 24 | vertices(2:3:end,:) = edges2; 25 | vertices(3:3:end,:) = edges3; 26 | 27 | %repeated sets of nodes (joint edges) are eliminated 28 | bedges2nodes = deleterepeatedrows(vertices); 29 | end 30 | 31 | matrix = [edges2nodes; bedges2nodes]; 32 | [matrixs,tags] = sortrows(sort(matrix,2)); 33 | 34 | % which ones were reps? k is a vector of indexes to matrixs. 35 | k = find(all(diff(matrixs)==0,2)); 36 | 37 | % tags(k) is an index vector to edge2nodes (matrix) and denotes those edges 38 | % which are on boundary 39 | % tags(k+1) is an index vector to matrix and matrix(tags(k+a)) is the 40 | % same as bedges2nodes, but in different order. 41 | 42 | % we could just return tags(k), but we want that the order is the same 43 | % as in bedges2nodes 44 | [~,tags2]=sort(tags(k+1)); 45 | bedges2edges = tags(k(tags2)); 46 | 47 | end -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/get_boundary_faces.m: -------------------------------------------------------------------------------- 1 | function bfaces2nodes = get_boundary_faces(elems2faces,faces2nodes) 2 | 3 | % GETBOUNDARYFACES 4 | % Calculates the boundary faces by their nodes for 3D mesh. In 2D this 5 | % data is calculated by 'refinement_uniform()'. 6 | % 7 | % IN: elems2faces elements by their faces 8 | % face2nodes faces by their nodes 9 | % 10 | % OUT: bfaces2nodes boundary faces by their nodes 11 | % 12 | 13 | is_quad = 0; 14 | n_col_E = 8; 15 | col_E_ind = 5:8; 16 | 17 | if size(elems2faces,2) == 6 18 | is_quad = 1; 19 | n_col_E = 12; 20 | col_E_ind = 7:12; 21 | end 22 | 23 | 24 | [A1,I1] = sort(elems2faces(:,1)); 25 | [A2,I2] = sort(elems2faces(:,2)); 26 | [A3,I3] = sort(elems2faces(:,3)); 27 | [A4,I4] = sort(elems2faces(:,4)); 28 | if is_quad 29 | [A5,I5] = sort(elems2faces(:,5)); 30 | [A6,I6] = sort(elems2faces(:,6)); 31 | end 32 | 33 | nfaces = max(max(elems2faces)); 34 | E = zeros(nfaces,n_col_E); 35 | 36 | E(A1,1) = I1; 37 | E(A2,2) = I2; 38 | E(A3,3) = I3; 39 | E(A4,4) = I4; 40 | if is_quad 41 | E(A5,5) = I5; 42 | E(A6,6) = I6; 43 | end 44 | 45 | % If the same face is listed in the same row of 'elems2faces' more than, 46 | % once it will simply be missed! Because of this we have to insert the 47 | % following dummy variables in order to determine the boundary faces. 48 | ind1 = (diff(A1) == 0); 49 | ind2 = (diff(A2) == 0); 50 | ind3 = (diff(A3) == 0); 51 | ind4 = (diff(A4) == 0); 52 | if is_quad 53 | ind5 = (diff(A5) == 0); 54 | ind6 = (diff(A6) == 0); 55 | end 56 | 57 | E(A1(ind1),col_E_ind(1)) = 1; 58 | E(A2(ind2),col_E_ind(2)) = 1; 59 | E(A3(ind3),col_E_ind(3)) = 1; 60 | E(A4(ind4),col_E_ind(4)) = 1; 61 | if is_quad 62 | E(A5(ind5),col_E_ind(5)) = 1; 63 | E(A6(ind6),col_E_ind(6)) = 1; 64 | end 65 | 66 | % final sorting 67 | E = sort(E,2,'descend'); 68 | 69 | % Get boundary nodes by first examining which columns in E 70 | % have only one nonzero element, meaning that this face is 71 | % related to only one single tetra, which means it is on the 72 | % boundary of the domain. Since faces are defined by their nodes, 73 | % we have the boundary nodes too. 74 | ind = (E(:,2) == 0); 75 | bfaces2nodes = faces2nodes(ind,:); 76 | 77 | end 78 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/get_boundary_nodes.m: -------------------------------------------------------------------------------- 1 | function bnodes = get_boundary_nodes(elems2nodes) 2 | %works only on 2D triangular and 3D tetrahedral meshes! 3 | 4 | %2D case 5 | if (size(elems2nodes,2)==3) 6 | if 0 7 | [elems2edges, edges2nodes]=get_edges(elems2nodes) 8 | %add on 9 | edge2elems=entryInWhichRows(elems2edges); 10 | if (size(edge2elems,2)==1) 11 | edge2elems=[edge2elems 0*edge2elems]; %all edges are boundary edges!!! 12 | end 13 | node2edges=entryInWhichRows(edge2nodes); 14 | else 15 | [edge2nodes, edge2elems, ~, ~]=getEdges(elems2nodes); 16 | end 17 | 18 | I= edge2elems(:,2)==0; 19 | bnodes=unique(edge2nodes(I,:)); 20 | end 21 | 22 | %3D case 23 | if (size(elems2nodes,2)==4) 24 | [elems2faces, faces2nodes]=get_faces(elems2nodes); 25 | 26 | %add on 27 | face2elems=entryInWhichRows(elems2faces); 28 | if (size(face2elems,2)==1) 29 | face2elems=[face2elems 0*face2elems]; %all edges are boundary edges!!! 30 | end 31 | node2faces=entryInWhichRows(faces2nodes); 32 | 33 | I= face2elems(:,2)==0; 34 | bnodes=unique(faces2nodes(I,:)); 35 | 36 | end 37 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/get_edges.m: -------------------------------------------------------------------------------- 1 | function [elems2edges, edges2nodes]=get_edges(elems2nodes) 2 | %function: [element2edges, edge2nodes]=get_edges(elems2nodes) 3 | %requires: deleterepeatedrows 4 | %generates edges of (triangular) triangulation defined in elems2nodes 5 | %elems2nodes is matrix, whose rows contain numbers of its element nodes 6 | %element2edges returns edges numbers of each triangular element 7 | %edge2nodes returns two node numbers of each edge 8 | %example in 2D: [element2edges, edge2nodes]=get_edges([1 2 3; 2 4 3]) 9 | %example in 3D: [element2edges, edge2nodes]=get_edges([1 2 3 4; 1 2 3 5; 1 2 4 6]) 10 | 11 | %2D case 12 | if (size(elems2nodes,2)==3) 13 | %extracts sets of edges 14 | edges1=elems2nodes(:,[2 3]); 15 | edges2=elems2nodes(:,[3 1]); 16 | edges3=elems2nodes(:,[1 2]); 17 | 18 | %as sets of their nodes (vertices) 19 | vertices=zeros(size(elems2nodes,1)*3,2); 20 | vertices(1:3:end,:)=edges1; 21 | vertices(2:3:end,:)=edges2; 22 | vertices(3:3:end,:)=edges3; 23 | 24 | %repeated sets of nodes (joint edges) are eliminated 25 | [edges2nodes,elems2edges]=deleterepeatedrows(vertices); 26 | elems2edges=reshape(elems2edges,3,size(elems2nodes,1))'; 27 | end 28 | 29 | %3D case 30 | if (size(elems2nodes,2)==4) 31 | %extracts sets of edges 32 | edges1=elems2nodes(:,[1 2]); 33 | edges2=elems2nodes(:,[1 3]); 34 | edges3=elems2nodes(:,[1 4]); 35 | edges4=elems2nodes(:,[2 3]); 36 | edges5=elems2nodes(:,[3 4]); 37 | edges6=elems2nodes(:,[4 2]); 38 | 39 | %as sets of their nodes (vertices) 40 | vertices=zeros(size(elems2nodes,1)*6,2); 41 | vertices(1:6:end,:)=edges1; 42 | vertices(2:6:end,:)=edges2; 43 | vertices(3:6:end,:)=edges3; 44 | vertices(4:6:end,:)=edges4; 45 | vertices(5:6:end,:)=edges5; 46 | vertices(6:6:end,:)=edges6; 47 | 48 | %repeated sets of nodes (joint edges) are eliminated 49 | [edges2nodes,elems2edges]=deleterepeatedrows(vertices); 50 | elems2edges=reshape(elems2edges,6,size(elems2nodes,1))'; 51 | end 52 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/get_faces.m: -------------------------------------------------------------------------------- 1 | function [elems2faces, faces2nodes]=get_faces(elems2nodes) 2 | %function: [element2faces, face2nodes]=get_faces(elems2nodes) 3 | %generates faces of a tetrahedral or hexahedral mesh 4 | %requires: deleterepeatedrows 5 | %input: elems2nodes - matrix, the i-th row contains numbers of nodes corresponding to the i-th elements 6 | %output: elems2faces - matrix, the i-th row contains numbers of faces corresponding to the i-th elements 7 | %output: faces2nodes - matrix, the i-th row contains numbers of nodes corresponding to the i-th face 8 | %example: [element2faces, face2nodes]=get_faces([1 3 4 5; 7 4 3 5; 5 7 6 4; 6 8 7 4; 2 1 4 5; 2 4 6 5]) 9 | 10 | switch size(elems2nodes,2) 11 | case {4,10} %tetrahedral mesh using P1 elements 12 | is_quad = 0; % flag if the surface is rectangle or triangle 13 | n_surf_nodes = 3; % number of main vertex on the surface 14 | n_surf = 4; % number of faces for each element 15 | %n_main_nodes = 4; % number of main vertices on the element 16 | case {8,20} 17 | is_quad = 1; 18 | n_surf = 6; 19 | n_surf_nodes = 4; 20 | %n_main_nodes = 8; 21 | end 22 | 23 | %extracts sets of faces 24 | if ~is_quad 25 | faces1=elems2nodes(:,[1 2 3]); 26 | faces2=elems2nodes(:,[1 2 4]); 27 | faces3=elems2nodes(:,[1 3 4]); 28 | faces4=elems2nodes(:,[2 3 4]); 29 | else 30 | faces1=elems2nodes(:,[1 2 3 4]); 31 | faces2=elems2nodes(:,[1 2 6 5]); 32 | faces3=elems2nodes(:,[1 4 8 5]); 33 | faces4=elems2nodes(:,[2 3 7 6]); 34 | faces5=elems2nodes(:,[3 4 8 7]); 35 | faces6=elems2nodes(:,[5 6 7 8]); 36 | end 37 | 38 | %as sets of their nodes (vertices) 39 | vertices=zeros(size(elems2nodes,1)*n_surf,n_surf_nodes); 40 | vertices(1:n_surf:end,:)=faces1; 41 | vertices(2:n_surf:end,:)=faces2; 42 | vertices(3:n_surf:end,:)=faces3; 43 | vertices(4:n_surf:end,:)=faces4; 44 | if is_quad 45 | vertices(5:n_surf:end,:)=faces5; 46 | vertices(6:n_surf:end,:)=faces6; 47 | end 48 | 49 | %repeated sets of nodes (joint faces) are eliminated 50 | [faces2nodes,elems2faces] = deleteRepeatedRows(vertices); 51 | elems2faces = reshape(elems2faces,n_surf,size(elems2nodes,1))'; 52 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/get_midpoints.m: -------------------------------------------------------------------------------- 1 | function midp = get_midpoints( elems2nodes, nodes2coord ) 2 | 3 | %MIDPOINTS 4 | % Calculate midpoints of the elements of the mesh 5 | % 6 | % SYNTAX: midp = get_midpoints( nodes2coord ) 7 | % 8 | % IN: elems2nodes elements by their nodes 9 | % nodes2coord nodes by their coordinates 10 | % 11 | % 12 | % OUT: midp middle points of elements 13 | % 14 | 15 | dim = size(nodes2coord,2); 16 | 17 | if ( dim==2 ) 18 | midp = ( nodes2coord(elems2nodes(:,1),:) + ... 19 | nodes2coord(elems2nodes(:,2),:) + ... 20 | nodes2coord(elems2nodes(:,3),:) ) ./ 3; 21 | elseif (dim==3) 22 | midp = ( nodes2coord(elems2nodes(:,1),:) + ... 23 | nodes2coord(elems2nodes(:,2),:) + ... 24 | nodes2coord(elems2nodes(:,3),:) + ... 25 | nodes2coord(elems2nodes(:,4),:) ) ./ 4; 26 | else 27 | error('GET_MIDPOINTS: An error calculating the midpoints of elements.') 28 | end 29 | 30 | end 31 | 32 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/refinement_uniform.m: -------------------------------------------------------------------------------- 1 | function [coordinates,elements,dirichlet,neumann]=refinement_uniform(coordinates,elements,dirichlet,neumann) 2 | %function: [coordinates,elements3,dirichlet]=refinement_uniform(coordinates,elements3,dirichlet) 3 | %requires: getEdges 4 | %uniform refinement of a 2D triangulation 5 | 6 | %uniform refinement 7 | [edge2nodes, ~, element2edges, ~]=getEdges(elements); 8 | nodes2edge_sparse=sparse(edge2nodes(:,1),edge2nodes(:,2),1:size(edge2nodes,1),size(coordinates,1),size(coordinates,1)); 9 | nodes2edge_sparse=symetrizeMatrix(nodes2edge_sparse); 10 | 11 | %elements on uniformly refined mesh 12 | elements3_internal=element2edges+size(coordinates,1); 13 | elements3_refin1= [elements(:,1) elements3_internal(:,3) elements3_internal(:,2)]; 14 | elements3_refin2= [elements(:,2) elements3_internal(:,1) elements3_internal(:,3)]; 15 | elements3_refin3= [elements(:,3) elements3_internal(:,2) elements3_internal(:,1)]; 16 | elements=[elements3_internal; elements3_refin1; elements3_refin2; elements3_refin3]; 17 | 18 | if (nargin>=3) 19 | %dirichlet edges of uniformly refined mesh 20 | dirichlet_edges=diag(nodes2edge_sparse(dirichlet(:,1),dirichlet(:,2))); 21 | dirichlet=[dirichlet(:,1) dirichlet_edges+size(coordinates,1); dirichlet_edges+size(coordinates,1) dirichlet(:,2)]; 22 | end 23 | 24 | if (nargin==4) 25 | if ~isempty(neumann) 26 | %neumann edges of uniformly refined mesh 27 | neumann_edges=diag(nodes2edge_sparse(neumann(:,1),neumann(:,2))); 28 | neumann=[neumann(:,1) neumann_edges+size(coordinates,1); neumann_edges+size(coordinates,1) neumann(:,2)]; 29 | end 30 | end 31 | 32 | %coordinates of uniformly refined mesh 33 | coordinates_internal=(coordinates(edge2nodes(:,1),:)+coordinates(edge2nodes(:,2),:))/2; 34 | coordinates=[coordinates; coordinates_internal]; 35 | 36 | function A_sym = symetrizeMatrix(A) 37 | [i,j,k]=find(A); 38 | W=sparse([i; j], [j; i], ones(size(k,1)*2,1)); 39 | A_help=sparse([i; j], [j; i], [k; k]); 40 | [i,j,k]=find(A_help); 41 | [i,j,kk]=find(W); 42 | A_sym=sparse(i,j,(kk.^(-1)).*k); %Now Kantennr_sym is a symetric form of Kantennr -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/refinement_uniform3D.m: -------------------------------------------------------------------------------- 1 | function [coordinates,elements3,dirichlet]=refinement_uniform3D(coordinates,elements3,dirichlet) 2 | %function: [coordinates,elements3,dirichlet]=refinement_uniform(coordinates,elements3,dirichlet) 3 | %uniform refinement of a 3D triangulation 4 | 5 | %uniform refinement 6 | [coordinates,elements3]=tetrarefine3(coordinates,elements3); 7 | %Dirichlet not working yet!!! 8 | 9 | %[coordinates,elements3]=tetrarefine4(coordinates,elements3,[],[],[]); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/refinement_uniform_2D.m: -------------------------------------------------------------------------------- 1 | function [nodes2coord,elems2nodes,dirichlet]=refinement_uniform_2D(nodes2coord,elems2nodes,dirichlet) 2 | %function: [nodes2coord,elems2nodes,dirichlet]=refinement_uniform_2D(nodes2coord,elems2nodes,dirichlet) 3 | %requires: get_edges 4 | %uniform refinement of a 2D triangulation 5 | 6 | %uniform refinement 7 | [elems2edges, edges2nodes]=get_edges(elems2nodes); 8 | nodes2edge=sparse(edges2nodes(:,1),edges2nodes(:,2),1:size(edges2nodes,1),size(nodes2coord,1),size(nodes2coord,1)); 9 | nodes2edge=symetrizeMatrix(nodes2edge); 10 | 11 | %elements on uniformly refined mesh 12 | elements_internal=elems2edges+size(nodes2coord,1); 13 | elements_refin1= [elems2nodes(:,1) elements_internal(:,3) elements_internal(:,2)]; 14 | elements_refin2= [elems2nodes(:,2) elements_internal(:,1) elements_internal(:,3)]; 15 | elements_refin3= [elems2nodes(:,3) elements_internal(:,2) elements_internal(:,1)]; 16 | elems2nodes=[elements_internal; elements_refin1; elements_refin2; elements_refin3]; 17 | 18 | if (nargin==3) 19 | %dirichlet edges of uniformly refined mesh 20 | dirichlet_edges=diag(nodes2edge(dirichlet(:,1),dirichlet(:,2))); 21 | dirichlet=[dirichlet(:,1) dirichlet_edges+size(nodes2coord,1); dirichlet_edges+size(nodes2coord,1) dirichlet(:,2)]; 22 | end 23 | 24 | 25 | %coordinates of uniformly refined mesh 26 | coordinates_internal=(nodes2coord(edges2nodes(:,1),:)+nodes2coord(edges2nodes(:,2),:))/2; 27 | nodes2coord=[nodes2coord; coordinates_internal]; 28 | 29 | function A_sym = symetrizeMatrix(A) 30 | [i,j,k]=find(A); 31 | W=sparse([i; j], [j; i], ones(size(k,1)*2,1)); 32 | A_help=sparse([i; j], [j; i], [k; k]); 33 | [i,j,k]=find(A_help); 34 | [i,j,kk]=find(W); 35 | A_sym=sparse(i,j,(kk.^(-1)).*k); %Now Kantennr_sym is a symetric form of Kantennr -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/refinement_uniform_3D.m: -------------------------------------------------------------------------------- 1 | function [nodes2coord,elems2nodes,dirichlet]=refinement_uniform_3D(nodes2coord,elems2nodes,dirichlet) 2 | %function: [nodes2coord,elems2nodes,dirichlet]=refinement_uniform_3D(nodes2coord,elems2nodes,dirichlet) 3 | %uniform refinement of a 3D triangulation 4 | 5 | %uniform refinement 6 | [nodes2coord,elems2nodes]=tetrarefine3(nodes2coord,elems2nodes); 7 | %Dirichlet not working yet!!! 8 | 9 | %[coordinates,elements3]=tetrarefine4(coordinates,elements3,[],[],[]); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/signs_edges.m: -------------------------------------------------------------------------------- 1 | function signs = signs_edges(elems2nodes) 2 | 3 | % SIGNS_EDGES 4 | % Calculate signs for the edges of a 2D/3D mesh. 5 | % 6 | % This data is needed in order to use linear Nedelec's elements in 2D/3D 7 | % and the linear Raviart-Thomas element in 2D. For the linear Raviart- 8 | % Thomas element in 3D we need signs related to faces, and this data is 9 | % provided by the function 'signs_faces(...)'. 10 | % 11 | % The edge signs can be easily deduced from the mesh data itself by 12 | % directly using the data structure which represents the elements 13 | % (triangles or tetrahedrons) by their nodes. The signs are obtained 14 | % with minimal matrix operations in a vectorized manner. 15 | % 16 | % SYNTAX: signs = signs_edges(elements) 17 | % 18 | % IN: elems2nodes Elements by their nodes. 19 | % In 2D, elements(i,1:3) are the three nodes of the i'th 20 | % triangle, and in 3D elements(i,1:6) are the six nodes of 21 | % the i'th tetrahedron. 22 | % 23 | % OUT: signs Signs for element edges, corresponding to the data 24 | % structure 'elements': signs(i,j) is the sign related to 25 | % the j'th edge of the i'th triangle (or tetrahedron). 26 | % 27 | 28 | dim = size(elems2nodes,2)-1; 29 | 30 | if ( dim == 2 ) 31 | tmp = elems2nodes(:,[2 3 1]) - elems2nodes(:,[3 1 2]); 32 | signs = tmp ./ abs(tmp); 33 | elseif (dim == 3) 34 | tmp = elems2nodes(:,[1 1 1 2 3 4]) - elems2nodes(:,[2 3 4 3 4 2]); 35 | signs = tmp ./ abs(tmp); 36 | else 37 | error('The data is not understood.') 38 | end 39 | 40 | end -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/signs_faces.m: -------------------------------------------------------------------------------- 1 | function signs = signs_faces(nodes2coord,elems2faces,faces2nodes,B_K) 2 | 3 | % SIGNS_FACES 4 | % Calculate signs for the faces of a 3D mesh (tetrahedrons). 5 | % 6 | % This data is needed for the linear Raviart-Thomas elements in 3D. In 7 | % 2D the signs are related to edges, and the edge signs are calculated 8 | % by the function 'signs_edges(...)'. 9 | % 10 | % Unlike sign calculation for edges, the orientation of faces cannot 11 | % be deduced directly from the mesh data. Instead, we must first choose 12 | % a positive normal direction for each face. Then we simply calculate 13 | % the outward normals for each tetrahedron's face, and compare it to the 14 | % chosen positive normal direction. 15 | % 16 | % The face signs are obtained with matrix operations in a vectorized 17 | % manner. However, the number of matrix operations is much more higher 18 | % than in edge sign calculation, making it considerably slower. 19 | % 20 | % SYNTAX: signs = signs_faces(coordinates, elems2faces, faces2nodes, B_K) 21 | % 22 | % IN: nodes2coord nodes by coordinates 23 | % elems2faces elements by their faces 24 | % faces2nodes faces by their nodes 25 | % B_K the matrix part of the affine transformations 26 | % 27 | % OUT: signs signs for element faces, corresponding to the data 28 | % structure 'elems2faces': signs(i,j) is the sign 29 | % related to the j'th face of the i'th tetrahedron. 30 | % 31 | 32 | dim = size(B_K,1); 33 | if ( dim ~= 3 ) 34 | error('Face signs can be calculated only in 3D.') 35 | end 36 | 37 | % calculate normal vector for each face, and let us choose this 38 | % normal direction as the positive direction 39 | p1 = nodes2coord(faces2nodes(:,1),1:3); % first, 40 | p2 = nodes2coord(faces2nodes(:,2),1:3); % second, 41 | p3 = nodes2coord(faces2nodes(:,3),1:3); % and third points of faces 42 | vec1 = p2-p1; % two vectors defining 43 | vec2 = p3-p1; % the face plane 44 | normals = cross(vec1,vec2,2); % normals 45 | 46 | % outward normals of the element's four faces 47 | % (note that there is no need to normalize the normals) 48 | B_K_invT = amt(aminv(B_K)); 49 | n1 = squeeze(amsv(B_K_invT, [ 0 0 -1]))'; 50 | n2 = squeeze(amsv(B_K_invT, [ 0 -1 0]))'; 51 | n3 = squeeze(amsv(B_K_invT, [-1 0 0]))'; 52 | n4 = squeeze(amsv(B_K_invT, [ 1 1 1]))'; 53 | 54 | % calculate the product of the positive normals and the 55 | % outward normals of the element faces 56 | tmp(:,1) = sum(normals(elems2faces(:,1),:) .* n1 , 2); 57 | tmp(:,2) = sum(normals(elems2faces(:,2),:) .* n2 , 2); 58 | tmp(:,3) = sum(normals(elems2faces(:,3),:) .* n3 , 2); 59 | tmp(:,4) = sum(normals(elems2faces(:,4),:) .* n4 , 2); 60 | 61 | % if the outward normal is in the same direction as the 62 | % chosen positive normal direction, it has a sign +1 63 | signs = tmp ./ abs(tmp); 64 | 65 | end -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_meshing/tetrarefine3.m: -------------------------------------------------------------------------------- 1 | function [XYZ,Elm,ERef] = tetrarefine3(XYZ,Elm,ERef); 2 | % author: Ales Janka, ales.janka@unifr.ch, http://perso.unifr.ch/ales.janka 3 | % function [XYZ,Elm,ERef] = tetrarefine3(XYZ,Elm,ERef); 4 | % refines tetrahedras bu cutting each edge in half and making 8 new 5 | % finer tetrahedra out of one corser one. 6 | % old nodal coords come first in XYZ, then the new ones 7 | % The new tetrahedra are similar to the old one, 8 | % no degeneration is supposed to occur as at most 3 congruence classes of 9 | % tetrahedra appear, even when re-applied iteratively (provided that 10 | % Elm() is not modified between two applications - ordering of vertices 11 | % in tetrahedra matters not only for positivity of volumes). 12 | %*** References: 13 | % Juergen Bey: Simplicial grid refinement: on Freudenthal s algorithm and 14 | % the optimal number of congruence classes, Numer.Math. 85 (2000), 15 | % no. 1, 1--29, or 16 | % Juergen Bey: Tetrahedral grid refinement, Computing 55 (1995), 17 | % no. 4, 355--378, or 18 | % http://citeseer.ist.psu.edu/bey95tetrahedral.html 19 | %*** Obsoletes the observations in: 20 | % Carre G., Carte G., Guillard H., Lanteri S.: Multigrid strategies for 21 | % CFD problems on non-structured meshes, Multigrid methods, VI 22 | % (European MG conference Gent 1999), 1--10, 23 | % Lect.Notes.Comput.Sci.Engrg. 190 (2000), no. 11-12, 1467--1482. 24 | 25 | nelm = size(Elm,1); 26 | nnod = size(XYZ,1); 27 | 28 | if (nargin<3) 29 | ERef=[]; 30 | end; 31 | 32 | %fprintf('--- midsides begin\n'); 33 | edge = [1 2; 34 | 1 3; 35 | 1 4; 36 | 2 3; 37 | 2 4; 38 | 3 4]; 39 | Edges = Elm(:,edge(1,:)); 40 | [Edges,I,J] = unique(sort(Edges,2),'rows'); 41 | clear I 42 | for i=2:6 43 | n = size(Edges,1); 44 | Edges = [Edges;Elm(:,edge(i,:))]; 45 | n1 = size(Edges,1); 46 | [Edges,I1,J1] = unique(sort(Edges,2),'rows'); 47 | clear I1 48 | J = [J1(J);J1(n+1:n1,1)]; 49 | clear J1 50 | end; 51 | %fprintf('--- midsides done\n'); 52 | 53 | XYZ = [XYZ; (XYZ(Edges(:,1),:) + XYZ(Edges(:,2),:))/2]; 54 | J = J+nnod; 55 | 56 | clear Edges 57 | 58 | Elm = [Elm, reshape(J,nelm,6)]; 59 | clear J 60 | 61 | %fprintf('--- elements begin\n'); 62 | Elm = [Elm(:, 1) Elm(:, 5) Elm(:, 6) Elm(:, 7), ... 63 | Elm(:, 5) Elm(:, 2) Elm(:, 8) Elm(:, 9), ... 64 | Elm(:, 6) Elm(:, 8) Elm(:, 3) Elm(:, 10), ... 65 | Elm(:, 7) Elm(:, 9) Elm(:,10) Elm(:, 4), ... 66 | Elm(:, 5) Elm(:, 6) Elm(:, 7) Elm(:, 9), ... 67 | Elm(:, 8) Elm(:, 6) Elm(:, 5) Elm(:, 9), ... 68 | Elm(:, 6) Elm(:, 7) Elm(:, 9) Elm(:,10), ... 69 | Elm(:, 9) Elm(:, 8) Elm(:, 6) Elm(:,10)]; 70 | Elm = Elm'; 71 | Elm = reshape(Elm,4,8*nelm); 72 | Elm = Elm'; 73 | if ~isempty(ERef); 74 | ERef = ERef * [1 1 1 1 1 1 1 1]; 75 | ERef = reshape(ERef',8*nelm,1); 76 | end; 77 | %fprintf('--- elements done\n'); 78 | 79 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/create_2D_mesh.m: -------------------------------------------------------------------------------- 1 | if demo==0 2 | %for demo=0 3 | %coarse mesh of the unit square (-0.5, 0.5)^2 (with half middle edge boundary) 4 | coordinates=0.5*[0 0; 1 0; 2 0; 2 1; 1 1; 0 1; 0 2; 1 2; 2 2]; 5 | elements=[1 2 5; 5 6 1; 2 3 4; 2 4 5; 6 5 8; 6 8 7; 5 4 9; 5 9 8]; 6 | dirichlet=[1 2; 2 3; 3 4; 4 5; 4 9; 9 8; 8 7; 7 6; 6 1]; 7 | 8 | %coarse mesh of the L-shape 9 | coordinates=[0 0; 1 0; 2 0; 2 1; 1 1; 0 1; 0 2; 1 2]; 10 | elements=[1 2 5; 5 6 1; 2 3 4; 2 4 5; 6 5 8; 6 8 7]; 11 | 12 | %coarse mesh of the L-shape (rotated) 13 | coordinates=[0 -2; -1 -1; 1 -1; 0 0; 2 0; 1 1; -1 1; 0 2]; 14 | elements=[1 3 2; 3 4 2; 3 5 4; 5 6 4; 4 6 7; 6 8 7]; 15 | dirichlet=[1 2; 2 3; 3 4; 4 5; 5 8; 8 7; 7 6; 6 1]; 16 | neumann=[]; 17 | else 18 | %coarse mesh of the unit square (0,1)^2 19 | coordinates=[0 0; 1 0; 0 1; 1 1]; 20 | elements=[1 2 3; 2 4 3]; 21 | %dirichlet=[1 2; 2 4; 4 3; 3 1]; 22 | 23 | if (demo==1) 24 | dirichlet=[1 2; 2 4; 4 3; 3 1]; 25 | neumann=[]; 26 | else %for demo>1 27 | dirichlet=[2 4; 4 3; 3 1]; 28 | neumann=[1 2]; 29 | end 30 | end 31 | 32 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/display_assembly_times.m: -------------------------------------------------------------------------------- 1 | fprintf('level=%d, ', level); 2 | fprintf('time spent on K: %6.1e seconds, ',time_stiffness_matrix); 3 | if exist('time_mass_matrix','var') 4 | fprintf('time spent on M: %6.1e seconds, ',time_mass_matrix); 5 | end 6 | fprintf('size of square matrix = %d ',row); 7 | fprintf('\n'); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/mass_matrixP1_2D.m: -------------------------------------------------------------------------------- 1 | function M=mass_matrixP1_2D(elements,areas,coeffs) 2 | %coeffs can be only P0 (elementwise constant) function 3 | %represented by a collumn vector with size(elements,1) entries 4 | %if coeffs is not provided then coeffs=1 is assumed globally 5 | %Note: P1 coeffs needs a higher integration rule (not implemented yet) 6 | 7 | X=kron(ones(1,3),elements); Y=kron(elements,ones(1,3)); 8 | 9 | if (nargin<3) 10 | Zmassmatrix=kron(areas,reshape((ones(3)+eye(3))/12,1,9)); 11 | else 12 | if numel(coeffs)==size(elements,1) %P0 coefficients 13 | Zmassmatrix=kron(areas.*coeffs,reshape((ones(3)+eye(3))/12,1,9)); 14 | else %P1 coefficients 15 | M1=[6 2 2; 2 2 1; 2 1 2]/60; 16 | M2=M1([3,1,2],[3,1,2]); 17 | M3=M2([3,1,2],[3,1,2]); 18 | 19 | Zmassmatrix=kron(areas.*coeffs(elements(:,1)),reshape(M1,1,9)) ... 20 | +kron(areas.*coeffs(elements(:,2)),reshape(M2,1,9)) ... 21 | +kron(areas.*coeffs(elements(:,3)),reshape(M3,1,9)); 22 | end 23 | 24 | end 25 | 26 | M=sparse(X,Y,Zmassmatrix); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/mass_matrixP1_2D_elasticity.m: -------------------------------------------------------------------------------- 1 | function M=mass_matrixP1_2D_elasticity(elements,areas) 2 | 3 | NE=size(elements,1); %number of elements 4 | 5 | elements_elasticity=2*elements(:,[1 1 2 2 3 3])-kron(ones(NE,1),[1,0,1,0,1,0]); 6 | NLB=6; 7 | Y_3D=reshape(repmat(elements_elasticity,1,NLB)',NLB,NLB,NE); 8 | X_3D=permute(Y_3D,[2 1 3]); 9 | 10 | Zlocal=zeros(6); 11 | Zlocal([1 3 5],[1 3 5])=(ones(3)+eye(3))/12; 12 | Zlocal([2 4 6],[2 4 6])=(ones(3)+eye(3))/12; 13 | Z_3D=astam(areas',repmat(Zlocal,[1 1 NE])); 14 | 15 | M=sparse(X_3D(:),Y_3D(:),Z_3D(:)); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/mass_matrixP1_3D.m: -------------------------------------------------------------------------------- 1 | function M=mass_matrixP1_3D(elements,volumes,coeffs) 2 | %coeffs can be only P0 (elementwise constant) function 3 | %represented by a collumn vector with size(elements,1) entries 4 | %if coeffs is not provided then coeffs=1 is assumed globally 5 | %Note: P1 coeffs needs a higher integration rule (not implemented yet) 6 | 7 | if 1 8 | Xscalar=kron(ones(1,4),elements); Yscalar=kron(elements,ones(1,4)); 9 | 10 | if (nargin<3) 11 | Zmassmatrix=kron(volumes,reshape((ones(4)+eye(4))/20,1,16)); 12 | else 13 | if numel(coeffs)==size(elements,1) %P0 coefficients 14 | Zmassmatrix=kron(volumes.*coeffs,reshape((ones(4)+eye(4))/20,1,16)); 15 | else %P1 coefficients 16 | M1=[6 2 2 2; 2 2 1 1; 2 1 2 1; 2 1 1 2]/120; 17 | M2=M1([4,1,2,3],[4,1,2,3]); 18 | M3=M2([4,1,2,3],[4,1,2,3]); 19 | M4=M3([4,1,2,3],[4,1,2,3]); 20 | 21 | Zmassmatrix=kron(volumes.*coeffs(elements(:,1)),reshape(M1,1,16)) ... 22 | +kron(volumes.*coeffs(elements(:,2)),reshape(M2,1,16)) ... 23 | +kron(volumes.*coeffs(elements(:,3)),reshape(M3,1,16)) ... 24 | +kron(volumes.*coeffs(elements(:,4)),reshape(M4,1,16)); 25 | end 26 | end 27 | 28 | M=sparse(Xscalar,Yscalar,Zmassmatrix); 29 | else 30 | NE=size(elements,1); %number of triangles 31 | 32 | %particular part for a given element in a given dimension 33 | NLB=4; %number of local basic functions, it must be known! 34 | IP=integration_point_transformation([-0.7236067977, -0.7236067977, -0.7236067977; ... 35 | 0.1708203932, -0.7236067977, -0.7236067977; ... 36 | -0.7236067977, 0.1708203932, -0.7236067977; ... 37 | -0.7236067977, -0.7236067977, 0.1708203932]); 38 | weight =[1/4 1/4 1/4 1/4]; 39 | phi=shapefun (IP,'P1'); 40 | Y=reshape(repmat(elements,1,NLB)',NLB,NLB,NE); 41 | 42 | %copy this part for a creation of a new element 43 | M_local=zeros(NLB); 44 | for i=1:size(IP,2) 45 | M_local=M_local+weight(i)*phi(:,i)*phi(:,i)'; 46 | end 47 | 48 | if (nargin<3) 49 | Z=astam(volumes,reshape(repmat(M_local,1,NE),NLB,NLB,NE)); 50 | else 51 | Z=astam(volumes.*coeffs,reshape(repmat(M_local,1,NE),NLB,NLB,NE)); 52 | end 53 | X=permute(Y,[2 1 3]); 54 | M=sparse(X(:),Y(:),Z(:)); 55 | end -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/mass_matrixP1_3D_elasticity.m: -------------------------------------------------------------------------------- 1 | function M=mass_matrixP1_3D_elasticity(elements,areas) 2 | 3 | %for elasticity in 2D 4 | NE=size(elements,1); %number of elements 5 | 6 | elements_elasticity=2*elements(:,[1 1 2 2 3 3])-kron(ones(NE,1),[1,0,1,0,1,0]); 7 | NLB=6; 8 | Y_3D=reshape(repmat(elements_elasticity,1,NLB)',NLB,NLB,NE); 9 | X_3D=permute(Y_3D,[2 1 3]); 10 | 11 | Zlocal=zeros(6); 12 | Zlocal([1 3 5],[1 3 5])=(ones(3)+eye(3))/12; 13 | Zlocal([2 4 6],[2 4 6])=(ones(3)+eye(3))/12; 14 | Z_3D=astam(areas',repmat(Zlocal,[1 1 NE])); 15 | 16 | M=sparse(X_3D(:),Y_3D(:),Z_3D(:)); 17 | 18 | 19 | %for laplace in 3D 20 | NE=size(elements,1); %number of triangles 21 | 22 | %particular part for a given element in a given dimension 23 | NLB=4; %number of local basic functions, it must be known! 24 | IP=integration_point_transformation([-0.7236067977, -0.7236067977, -0.7236067977; ... 25 | 0.1708203932, -0.7236067977, -0.7236067977; ... 26 | -0.7236067977, 0.1708203932, -0.7236067977; ... 27 | -0.7236067977, -0.7236067977, 0.1708203932]); 28 | weight =[1/4 1/4 1/4 1/4]; 29 | phi=shapefun (IP,'P1'); 30 | Y_3Dmatrix=reshape(repmat(elements,1,NLB)',NLB,NLB,NE); 31 | 32 | %copy this part for a creation of a new element 33 | M_local=zeros(NLB); 34 | for i=1:size(IP,2) 35 | M_local=M_local+weight(i)*phi(:,i)*phi(:,i)'; 36 | end 37 | M_local_3Dmatrix=astam(areas,reshape(repmat(M_local,1,NE),NLB,NLB,NE)); 38 | X_3Dmatrix=permute(Y_3Dmatrix,[2 1 3]); 39 | M=sparse(X_3Dmatrix(:),Y_3Dmatrix(:),M_local_3Dmatrix(:)); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/mass_tensorP1_2D.m: -------------------------------------------------------------------------------- 1 | function Z=mass_tensorP1_2D(elements,areas,coeffs) 2 | %coeffs can be only P0 (elementwise constant) function 3 | %represented by a collumn vector with size(elements,1) entries 4 | %if coeffs is not provided then coeffs=1 is assumed globally 5 | %Note: P1 coeffs needs a higher integration rule (not implemented yet) 6 | 7 | NE=size(elements,1); %number of elements 8 | Z_local=(ones(3)+eye(3))/12; 9 | 10 | Z=copy_matrix_to_3Dmatrix(Z_local,NE); 11 | 12 | if (nargin<3) 13 | Z=astam(areas',Z); 14 | else 15 | if numel(coeffs)==size(elements,1) %P0 coefficients 16 | Z=astam((areas.*coeffs)',Z); 17 | end 18 | end -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/mesh3D.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matlabfem/matlab_fem_elastoplasticity/25ba61c6888aa0f4834065ce10c6ebf46c3058b6/elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/mesh3D.mat -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/stiffness_matrixP1_2D.m: -------------------------------------------------------------------------------- 1 | function [A,areas,Z,X,Y]=stiffness_matrixP1_2D(elements,coordinates,coeffs) 2 | %coeffs can be either P0 (elementwise constant) or P1 (elementwise nodal) function 3 | %represented by a collumn vector with size(elements,1) or size(coordinates,1) entries 4 | %if coeffs is not provided then coeffs=1 is assumed globally 5 | 6 | NE=size(elements,1); %number of elements 7 | DIM=size(coordinates,2); %problem dimension 8 | 9 | %particular part for a given element in a given dimension 10 | NLB=3; %number of local basic functions, it must be known! 11 | coord=zeros(DIM,NLB,NE); 12 | for d=1:DIM 13 | for i=1:NLB 14 | coord(d,i,:)=coordinates(elements(:,i),d); 15 | end 16 | end 17 | IP=[1/3;1/3]; 18 | [dphi,jac] = phider(coord,IP,'P1'); 19 | dphi = squeeze(dphi); 20 | areas=abs(squeeze(jac))/factorial(DIM); 21 | 22 | if (nargin<3) 23 | Z=astam(areas',amtam(dphi,dphi)); 24 | else 25 | if numel(coeffs)==size(coordinates,1) %P1->P0 averaging 26 | coeffs=evaluate_average_point(elements,coeffs); 27 | end 28 | Z=astam((areas.*coeffs)',amtam( dphi,dphi)); 29 | end 30 | Y=reshape(repmat(elements,1,NLB)',NLB,NLB,NE); 31 | 32 | %copy this part for a creation of a new element 33 | X=permute(Y,[2 1 3]); 34 | A=sparse(X(:),Y(:),Z(:)); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/stiffness_matrixP1_2D_elasticity.m: -------------------------------------------------------------------------------- 1 | function [A,areas]=stiffness_matrixP1_2D_elasticity(elements,coordinates,lambda,mu) 2 | 3 | %for laplace 4 | NE=size(elements,1); %number of elements 5 | DIM=size(coordinates,2); %problem dimension 6 | 7 | %laplace 8 | NLB=3; %number of local basic functions, it must be known! 9 | coord=zeros(DIM,NLB,NE); 10 | for d=1:DIM 11 | for i=1:NLB 12 | coord(d,i,:)=coordinates(elements(:,i),d); 13 | end 14 | end 15 | IP=[1/3;1/3]; 16 | [dphi,jac] = phider(coord,IP,'P1'); %integration rule, it must be known! 17 | dphi = squeeze(dphi); 18 | areas=abs(squeeze(jac))/factorial(DIM); 19 | 20 | %elasticity matrix is derived from laplace matrix 21 | R=zeros(3,6,NE); 22 | R([1,3],[1,3,5],:)=dphi; 23 | R([3,2],[2,4,6],:)=dphi; 24 | clear dphi 25 | 26 | C=mu*[2 0 0;0 2 0;0 0 1] + lambda*[1 1 0;1 1 0;0 0 0]; 27 | 28 | Elements=2*elements(:,[1 1 2 2 3 3])-kron(ones(NE,1),[1,0,1,0,1,0]); 29 | NLB=6; 30 | Y=reshape(repmat(Elements,1,NLB)',NLB,NLB,NE); 31 | X=permute(Y,[2 1 3]); 32 | Z=astam(areas',amtam(R,smamt(C,permute(R,[2 1 3])))); 33 | 34 | A=sparse(X(:),Y(:),Z(:)); 35 | 36 | end 37 | 38 | 39 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/stiffness_matrixP1_3D.m: -------------------------------------------------------------------------------- 1 | function [A,volumes]=stiffness_matrixP1_3D(elements,coordinates,coeffs) 2 | %coeffs can be either P0 (elementwise constant) or P1 (elementwise nodal) function 3 | %represented by a collumn vector with size(elements,1) or size(coordinates,1) entries 4 | %if coeffs is not provided then coeffs=1 is assumed globally) 5 | 6 | NE=size(elements,1); %number of elements 7 | DIM=size(coordinates,2); %problem dimension 8 | 9 | %particular part for a given element in a given dimension 10 | NLB=4; %number of local basic functions, it must be known! 11 | coord=zeros(DIM,NLB,NE); 12 | for d=1:DIM 13 | for i=1:NLB 14 | coord(d,i,:)=coordinates(elements(:,i),d); 15 | end 16 | end 17 | IP=[1/4 1/4 1/4]'; 18 | [dphi,jac] = phider(coord,IP,'P1'); %integration rule, it must be known! 19 | 20 | volumes=abs(squeeze(jac))/factorial(DIM); 21 | 22 | dphi = squeeze(dphi); 23 | 24 | if (nargin<3) 25 | Z=astam(volumes',amtam(dphi,dphi)); 26 | else 27 | if numel(coeffs)==size(coordinates,1) %P1->P0 averaging 28 | coeffs=evaluate_average_point(elements,coeffs); 29 | end 30 | Z=astam((volumes.*coeffs)',amtam(dphi,dphi)); 31 | end 32 | 33 | Y=reshape(repmat(elements,1,NLB)',NLB,NLB,NE); 34 | %copy this part for a creation of a new element 35 | 36 | X=permute(Y,[2 1 3]); 37 | A=sparse(X(:),Y(:),Z(:)); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/stiffness_matrixP1_3D_elasticity.m: -------------------------------------------------------------------------------- 1 | function [K,areas]=stiffness_matrixP1_3D_elasticity(elements,coordinates,lambda,mu) 2 | 3 | %for laplace 4 | NE=size(elements,1); %number of elements 5 | DIM=size(coordinates,2); %problem dimension 6 | 7 | %laplace 8 | NLB=4; %number of local basic functions, it must be known! 9 | coord=zeros(DIM,NLB,NE); 10 | for d=1:DIM 11 | for i=1:NLB 12 | coord(d,i,:)=coordinates(elements(:,i),d); 13 | end 14 | end 15 | clear coordinates 16 | 17 | IP=[1/4 1/4 1/4]'; 18 | [dphi,jac] = phider(coord,IP,'P1'); %integration rule, it must be known! 19 | clear coord 20 | 21 | areas=abs(squeeze(jac))/factorial(DIM); 22 | clear jac 23 | 24 | %elasticity matrix is derived from laplace matrix, see paper 25 | %Matlab implementation of the FEM in Elasticity by 26 | %Alberty, Carstensen, Funken, Klose 27 | R=zeros(6,12,NE); 28 | R([1,4,5],1:3:10,:)=dphi; 29 | R([4,2,6],2:3:11,:)=dphi; 30 | R([5,6,3],3:3:12,:)=dphi; 31 | clear dphi 32 | 33 | C=mu*diag([2 2 2 1 1 1]) + lambda*kron([1 0; 0 0],ones(3)); 34 | 35 | Elements=3*elements(:,kron(1:4,[1 1 1]))... 36 | -kron(ones(NE,1),kron([1 1 1 1],[2 1 0])); 37 | clear elements 38 | 39 | Y=reshape(repmat(Elements,1,12)',12,12,NE); 40 | X=permute(Y,[2 1 3]); 41 | Z=astam(areas',amtam(R,smamt(C,permute(R,[2 1 3])))); 42 | K=sparse(X(:),Y(:),Z(:)); 43 | 44 | 45 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/stiffness_matrixP2_2D.m: -------------------------------------------------------------------------------- 1 | function [A,areas,Z,X,Y]=stiffness_matrixP2_2D(elements,coordinates,coeffs) 2 | %coeffs can be either P0 (elementwise constant) or P1 (elementwise nodal) function 3 | %represented by a collumn vector with size(elements,1) or size(coordinates,1) entries 4 | %if coeffs is not provided then coeffs=1 is assumed globally 5 | 6 | NE=size(elements,1); %number of elements 7 | DIM=size(coordinates,2); %problem dimension 8 | 9 | %particular part for a given element in a given dimension 10 | NLB=6; %number of local basic functions, it must be known! 11 | coord=zeros(DIM,NLB,NE); 12 | for d=1:DIM 13 | for i=1:NLB 14 | coord(d,i,:)=coordinates(elements(:,i),d); 15 | end 16 | end 17 | 18 | p=3; [IP,w]=inttri(p); IP=IP'; w=w*2; 19 | 20 | [dphi,jac] = phider(coord,IP,'P2'); 21 | 22 | areas=abs(squeeze(jac))/factorial(DIM); 23 | 24 | if p>=2 25 | areas=areas(1,:)'; 26 | end 27 | 28 | 29 | if (nargin<3) 30 | product=zeros(NLB,NLB,NE); 31 | for i=1:size(IP,2) 32 | product=product+w(i)*amtam(squeeze(dphi(:,:,i,:)),squeeze(dphi(:,:,i,:))); 33 | end 34 | Z=astam(areas,product); 35 | else 36 | if numel(coeffs)==size(coordinates,1) %P1->P0 averaging 37 | coeffs=evaluate_average_point(elements,coeffs); 38 | end 39 | Z=astam((areas.*coeffs)',amtam( dphi,dphi)); 40 | end 41 | Y=reshape(repmat(elements,1,NLB)',NLB,NLB,NE); 42 | 43 | %copy this part for a creation of a new element 44 | X=permute(Y,[2 1 3]); 45 | A=sparse(X(:),Y(:),Z(:)); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/stiffness_matrixQ1_3D_elasticity.m: -------------------------------------------------------------------------------- 1 | function [K,volumes]=stifness_matrixQ1_3D_elasticity(elements,coordinates,lambda,mu) 2 | % Compute stiffness matrix for hexahedral mesh 3 | % 4 | % Code extended by tdngo 5 | 6 | assert(size(elements,2) == 8); 7 | 8 | %for laplace 9 | NE=size(elements,1); %number of elements 10 | DIM=size(coordinates,2); %problem dimension 11 | 12 | %laplace 13 | NLB=8; %number of local basic functions, it must be known! 14 | coord=zeros(DIM,NLB,NE); 15 | for d=1:DIM 16 | for i=1:NLB 17 | coord(d,i,:)=coordinates(elements(:,i),d); 18 | end 19 | end 20 | clear coordinates 21 | 22 | p = -1/sqrt(3); 23 | q = 1/sqrt(3); 24 | IP= [p, p, p; % Integration points. Gauss quadrature, weight = 1 25 | p, p, q; 26 | p, q, p; 27 | p, q, q; 28 | q, p, p; 29 | q, p, q; 30 | q, q, p; 31 | q, q, q]'; 32 | 33 | [dphi,jac] = phider(coord,IP,'Q1'); %integration rule, it must be known! 34 | clear coord 35 | 36 | jac = abs(jac); 37 | 38 | % Elasticity matrix 39 | C=mu*diag([2 2 2 1 1 1]) + lambda*kron([1 0; 0 0],ones(3)); 40 | 41 | Elements=3*elements(:,kron(1:8,[1 1 1]))... 42 | -kron(ones(NE,1),kron(ones(1,8),[2 1 0])); 43 | clear elements 44 | 45 | Y=reshape(repmat(Elements,1,24)',24,24,NE); 46 | X=permute(Y,[2 1 3]); 47 | 48 | 49 | Z = 0; 50 | for i = 1:size(IP,2) % There are 8 integration Gaussian points 51 | R=zeros(6,24,NE); 52 | R([1,4,5],1:3:22,:)=dphi(:,:,i,:); % These indices because B = [dx 0 0; 0 dy 0; 0 0 dz; dy dx 0; dz 0 dx; 0 dz dy] 53 | R([4,2,6],2:3:23,:)=dphi(:,:,i,:); 54 | R([5,6,3],3:3:24,:)=dphi(:,:,i,:); 55 | 56 | Z = Z + astam(squeeze(jac(1,i,:))',amtam(R,smamt(C,permute(R,[2 1 3])))); 57 | end 58 | clear dphi 59 | 60 | K=sparse(X(:),Y(:),Z(:)); 61 | volumes = sum(jac); 62 | 63 | 64 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/stiffness_tensorP1_2D.m: -------------------------------------------------------------------------------- 1 | function Z=stiffness_tensorP1_2D(elements,coordinates,coeffs) 2 | %coeffs can be either P0 (elementwise constant) or P1 (elementwise nodal) function 3 | %represented by a collumn vector with size(elements,1) or size(coordinates,1) entries 4 | %if coeffs is not provided then coeffs=1 is assumed globally 5 | 6 | NE=size(elements,1); %number of elements 7 | DIM=size(coordinates,2); %problem dimension 8 | 9 | %particular part for a given element in a given dimension 10 | NLB=3; %number of local basic functions, it must be known! 11 | coord=zeros(DIM,NLB,NE); 12 | for d=1:DIM 13 | for i=1:NLB 14 | coord(d,i,:)=coordinates(elements(:,i),d); 15 | end 16 | end 17 | IP=[1/3;1/3]; 18 | [dphi,jac] = phider(coord,IP,'P1'); 19 | dphi = squeeze(dphi); 20 | areas=abs(squeeze(jac))/factorial(DIM); 21 | 22 | if (nargin<3) 23 | Z=astam(areas',amtam(dphi,dphi)); 24 | else 25 | if numel(coeffs)==size(coordinates,1) %P1->P0 averaging 26 | coeffs=evaluate_average_point(elements,coeffs); 27 | end 28 | Z=astam((areas.*coeffs)',amtam( dphi,dphi)); 29 | end -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_nodal_elements_rv/visualize_mesh.m: -------------------------------------------------------------------------------- 1 | if (level<2) 2 | subplot(1,2,level+1); show_mesh(elements,coordinates); axis image; title(strcat('mesh, level=',num2str(level))); 3 | 4 | % if demo>0 5 | % dn=unique(dirichlet); nn=unique(neumann); 6 | % hold on; show_nodes(coordinates,dn,nn); hold off 7 | % end 8 | end -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/amav.m: -------------------------------------------------------------------------------- 1 | function avb = amav (ama,avx) 2 | %new function by Jan Valdman 3 | 4 | % ama: ama(1:nx,1:ny,1:nz) 5 | % avx: avx(1:ny,1:nz) 6 | % avb: avb(1:nx,1:nz) 7 | 8 | [nx,ny,nz] = size(ama); 9 | 10 | avx = avx(:,ones(ny,1),:); 11 | 12 | avb = ama .* avx; 13 | avb = sum(avb,1); 14 | 15 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/amdet.m: -------------------------------------------------------------------------------- 1 | function dem = amdet (ama) 2 | % ama: ama(1:nx,1:nx,1:nz) 3 | % amb: amb(1:nx,1:nx,1:nz) 4 | 5 | [nx,nx,nz] = size(ama); 6 | 7 | if nx > 3, 8 | 9 | msg = 'Array operation for invertig matrices of dimension more '; 10 | msg = [msg 'than 3 (three) is not available, so the performance may be bad.']; 11 | error(msg); 12 | 13 | end 14 | 15 | if nx==1 16 | 17 | % Matrix determinant. 18 | dem = squeeze(ama); 19 | 20 | elseif nx==2 21 | 22 | % Matrix elements. 23 | a = squeeze(ama(1,1,:)); b = squeeze(ama(1,2,:)); 24 | c = squeeze(ama(2,1,:)); d = squeeze(ama(2,2,:)); 25 | 26 | % Matrix determinant. 27 | dem = a.*d - b.*c; 28 | 29 | else 30 | % Matrix elements. 31 | a = squeeze(ama(1,1,:)); b = squeeze(ama(1,2,:)); c = squeeze(ama(1,3,:)); 32 | d = squeeze(ama(2,1,:)); e = squeeze(ama(2,2,:)); f = squeeze(ama(2,3,:)); 33 | g = squeeze(ama(3,1,:)); h = squeeze(ama(3,2,:)); i = squeeze(ama(3,3,:)); 34 | 35 | % Matrix determinant. 36 | dem = a.*(e.*i - f.*h)-b.*(d.*i-f.*g)+c.*(d.*h-e.*g); 37 | end 38 | 39 | dem = dem(:)'; 40 | 41 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/aminv.m: -------------------------------------------------------------------------------- 1 | function [amb,dem] = aminv (ama) 2 | % ama: ama(1:nx,1:nx,1:nz) 3 | % amb: amb(1:nx,1:nx,1:nz) 4 | 5 | [nx,nx,nz] = size(ama); 6 | 7 | if nx > 3, 8 | 9 | msg = 'Array operation for invertig matrices of dimension more '; 10 | msg = [msg 'than 3 (three) is not available, so the performance may be bad.']; 11 | error(msg); 12 | 13 | end 14 | 15 | if nx==1 16 | 17 | % Matrix determinant. 18 | dem = squeeze(ama); 19 | 20 | % Matrix inverse. 21 | amb = zeros(nx,nx,nz); 22 | amb(nx,nx,:) = 1./ama(nx,nx,:); 23 | 24 | elseif nx==2 25 | 26 | % Matrix elements. 27 | a = squeeze(ama(1,1,:)); b = squeeze(ama(1,2,:)); 28 | c = squeeze(ama(2,1,:)); d = squeeze(ama(2,2,:)); 29 | 30 | % Matrix determinant. 31 | dem = a.*d - b.*c; 32 | 33 | % Matrix inverse. 34 | amb = zeros(nx,nx,nz); 35 | amb(1,1,:) = d./dem; 36 | amb(2,2,:) = a./dem; 37 | amb(1,2,:) = - b./dem; 38 | amb(2,1,:) = - c./dem; 39 | 40 | else 41 | % Matrix elements. 42 | a = squeeze(ama(1,1,:)); b = squeeze(ama(1,2,:)); c = squeeze(ama(1,3,:)); 43 | d = squeeze(ama(2,1,:)); e = squeeze(ama(2,2,:)); f = squeeze(ama(2,3,:)); 44 | g = squeeze(ama(3,1,:)); h = squeeze(ama(3,2,:)); i = squeeze(ama(3,3,:)); 45 | 46 | % Matrix determinant. 47 | dem = a.*(e.*i - f.*h)-b.*(d.*i-f.*g)+c.*(d.*h-e.*g); 48 | 49 | % Matrix inverse. 50 | %cofactors 51 | C11=e.*i - f.*h; 52 | C12=-(d.*i-f.*g); 53 | C13=d.*h-e.*g; 54 | C21=-(b.*i-c.*h); 55 | C22=a.*i-c.*g; 56 | C23=-(a.*h-b.*g); 57 | C31=b.*f-c.*e; 58 | C32=-(a.*f-d.*c); 59 | C33=a.*e-b.*d; 60 | 61 | amb = zeros(nx,nx,nz); 62 | amb(1,1,:) = C11./dem; 63 | amb(2,1,:) = C12./dem; 64 | amb(3,1,:) = C13./dem; 65 | amb(1,2,:) = C21./dem; 66 | amb(2,2,:) = C22./dem; 67 | amb(3,2,:) = C23./dem; 68 | amb(1,3,:) = C31./dem; 69 | amb(2,3,:) = C32./dem; 70 | amb(3,3,:) = C33./dem; 71 | end 72 | 73 | dem = dem(:)'; 74 | 75 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/amsm.m: -------------------------------------------------------------------------------- 1 | function amb = amsm (ama,smx) 2 | % ama: ama(1:nx,1:ny,1:nz) 3 | % smx: smx(1:ny,1:nk) 4 | % amb: amb(1:nx,1:nk,1:nz) 5 | 6 | [nx,ny,nz] = size(ama); 7 | [ny,nk] = size(smx); 8 | 9 | amb = zeros(nx,nk,nz); 10 | for col = 1:nk 11 | 12 | amb(:,col,:) = amsv(ama,smx(:,col)); 13 | 14 | end 15 | 16 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/amsv.m: -------------------------------------------------------------------------------- 1 | function avb = amsv (ama,svx) 2 | % ama: ama(1:nx,1:ny,1:nz) 3 | % svx: svx(1:ny,1) 4 | % avb: avb(1:nx,1,1:nz) 5 | 6 | [nx,ny,nz] = size(ama); 7 | 8 | avx = svx(:).'; 9 | avx = avx(ones(nx,1),:,ones(nz,1)); 10 | 11 | avb = ama .* avx; 12 | avb = sum(avb,2); 13 | 14 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/amt.m: -------------------------------------------------------------------------------- 1 | function amb = amt (ama) 2 | % ama: ama(1:nx,1:ny,1:nz) 3 | % amb: amb(1:ny,1:nx,1:nz) 4 | 5 | [nx,ny,nz] = size(ama); 6 | 7 | row = [1:nx]'; row = row(:,ones(ny,1)); 8 | col = [1:ny]; col = col(ones(nx,1),:); 9 | ind = row + (col-1)*nx; 10 | ind = ind'; 11 | ind = ind(:,:,ones(nz,1)); 12 | off = [0:nx*ny:(nz-1)*nx*ny]; 13 | off = reshape(off(ones(nx*ny,1),:),ny,nx,nz); 14 | ind = ind + off; 15 | 16 | amb = ama(ind); 17 | 18 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/amtam.m: -------------------------------------------------------------------------------- 1 | function amb = amtam (amx,ama) 2 | % ama: ama(1:nx,1:ny,1:nz) 3 | % amx: amx(1:nx,1:nk,1:nz) 4 | % amb: amb(1:nk,1:ny,1:nz) 5 | 6 | [nx,ny,nz] = size(ama); 7 | [nx,nk,nz] = size(amx); 8 | 9 | amb = zeros(nk,ny,nz); 10 | for row = 1:nk 11 | 12 | amb(row,:,:) = avtam(amx(:,row,:),ama); 13 | 14 | end 15 | 16 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/astam.m: -------------------------------------------------------------------------------- 1 | function amb = astam (asx,ama) 2 | % ama: ama(1:nx,1:ny,1:nz) 3 | % asx: avx(1,1:nz) 4 | % amb: avb(1:nx,1:ny,1:nz) 5 | 6 | [nx,ny,nz] = size(ama); 7 | 8 | asx = reshape(asx,1,1,nz); 9 | asx = asx(ones(nx,1),ones(ny,1),:); 10 | 11 | amb = ama .* asx; 12 | 13 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/avtam.m: -------------------------------------------------------------------------------- 1 | function avb = avtam (avx,ama) 2 | % ama: ama(1:nx,1:ny,1:nz) 3 | % avx: avx(1:nx,1:nz) 4 | % avb: avb(1,1:ny,1:nz) 5 | 6 | [nx,ny,nz] = size(ama); 7 | 8 | avx = avx(:,ones(ny,1),:); 9 | 10 | avb = ama .* avx; 11 | avb = sum(avb,1); 12 | 13 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/avtamav.m: -------------------------------------------------------------------------------- 1 | function as = avtamav (ava,ama,avb) 2 | 3 | as=avtav(amt(avtam(ava,ama)),avb); 4 | 5 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/avtav.m: -------------------------------------------------------------------------------- 1 | function as = avtav (ava,avb) 2 | % ava: ava(1:nx,1,1:nz) 3 | % avb: ama(1:nx,1,1:nz) 4 | % as: as(1:nz,1) 5 | 6 | as=squeeze(sum(ava.*avb,1)); 7 | 8 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/conv_ma2av.m: -------------------------------------------------------------------------------- 1 | function av=conv_ma2av(ma) 2 | %converts matrix to array of vectors 3 | % ma: ma(1:nx, 1:ny) 4 | % av: av(1:y,1,1:nx) 5 | 6 | [nx,ny] = size(ma); 7 | av=zeros(ny,1,nx); 8 | 9 | for i=1:ny 10 | av(i,1,:)=ma(:,i); 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/conv_sm2am.m: -------------------------------------------------------------------------------- 1 | function ama = conv_sm2am (smx,nz) 2 | % ama: ama(1:ny,1:nx,1:nz) 3 | % smx: smx(1:nk,1:nx) 4 | % amb: amb(1:nk,1:ny,1:nz) 5 | 6 | [nk,nx] = size(smx); 7 | 8 | ama=zeros(nk,nx,nz); 9 | 10 | for row = 1:nk 11 | for col = 1:nx 12 | ama(row,col,:)=smx(row,col); 13 | end 14 | end 15 | 16 | 17 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/copy_matrix_to_3Dmatrix.m: -------------------------------------------------------------------------------- 1 | function Z = copy_matrix_to_3Dmatrix(Z_local,NE) 2 | Z=zeros(size(Z_local,1),size(Z_local,2),NE); 3 | for i=1:size(Z_local,1) 4 | for j=1:size(Z_local,2) 5 | Z(i,j,:)=Z_local(i,j); 6 | end 7 | end 8 | 9 | end 10 | 11 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/phider.m: -------------------------------------------------------------------------------- 1 | function [dphi,detj,jac] = phider (coord,point,etype) 2 | % PHIDER Returns the gradients of the basis functions 3 | % with respect to the local coordinates (x,y,...). 4 | % 5 | % coord : coord(nod,nos,noe), the local coordinates of the 6 | % nodes which the shape functions are associated with. 7 | % point : point(nod,nop), the coordinates of the 8 | % points on the reference element. 9 | % dphi : dphi(nod,nos,nop,noe), the gradients of the 10 | % shape functions (second) at all points (third) 11 | % with respect to the local cordinates. 12 | % jac : jac(nod,nod,nop,noe), the Jacobian matrices 13 | % at all nop points. 14 | % detj : detj(1,nop,noe), determinants of the Jacobian matrices 15 | % at all nop points 16 | % etype : 'P0','P1','P2', etc., the element type. 17 | % 18 | % Note: 19 | % nod - dimension of the element. 20 | % nop - number of points. 21 | % nos - number of shape functions. 22 | % noe - number of elements. 23 | 24 | jacout = 'no'; 25 | if nargout >2, jacout = 'yes'; end 26 | detout = 'no'; 27 | if nargout >1, detout = 'yes'; end 28 | 29 | nod = size(coord,1); 30 | nop = size(point,2); 31 | nos = size(coord,2); 32 | noe = size(coord,3); 33 | 34 | % Derivatives with respect to the reference 35 | % coordinates (xi,eta,...). 36 | dshape = shapeder(point,etype); 37 | 38 | if strcmp(jacout, 'yes'), jac = zeros(nod,nod,nop,noe); end 39 | if strcmp(detout,'yes'), detj = zeros(1,nop,noe); end 40 | dphi = zeros(nod,nos,nop,noe); 41 | 42 | for poi = 1:nop 43 | 44 | tjac = smamt(dshape(:,:,poi),coord); 45 | [tjacinv,tjacdet] = aminv(tjac); 46 | dphi(:,:,poi,:) = amsm(tjacinv,dshape(:,:,poi)); 47 | 48 | if strcmp(jacout, 'yes') 49 | jac(:,:,poi,:) = tjac; 50 | end 51 | if strcmp(detout, 'yes') 52 | detj(1,poi,:) = abs(tjacdet); 53 | end 54 | 55 | end 56 | 57 | return 58 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/quadratic_form_elementwise.m: -------------------------------------------------------------------------------- 1 | function value_elementwise=quadratic_form_elementwise(u,elements,K_3Dmatrix) 2 | u_3Dvector=conv_ma2av(u(elements)); 3 | value_elementwise=avtamav(u_3Dvector,K_3Dmatrix,u_3Dvector); 4 | end 5 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/smamt.m: -------------------------------------------------------------------------------- 1 | function amb = smamt (smx,ama) 2 | % ama: ama(1:ny,1:nx,1:nz) 3 | % smx: smx(1:nk,1:nx) 4 | % amb: amb(1:nk,1:ny,1:nz) 5 | 6 | [ny,nx,nz] = size(ama); 7 | [nk,nx] = size(smx); 8 | 9 | amb = zeros(nk,ny,nz); 10 | for row = 1:nk 11 | 12 | amb(row,:,:) = svamt(smx(row,:),ama); 13 | 14 | end 15 | 16 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_vectorization/svamt.m: -------------------------------------------------------------------------------- 1 | function avb = svamt (svx,ama) 2 | % ama: ama(1:ny,1:nx,1:nz) 3 | % svx: svx(1,1:nx) 4 | % avb: avb(1,1:ny,1:nz) 5 | 6 | [ny,nx,nz] = size(ama); 7 | 8 | avx = svx; 9 | avx = avx(ones(ny,1),:,ones(nz,1)); 10 | 11 | avb = ama .* avx; 12 | avb = sum(avb,2); 13 | avb = reshape(avb,1,ny,nz); 14 | 15 | return -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/draw_edges.m: -------------------------------------------------------------------------------- 1 | function draw_edges(edges,coordinates,format,Zmax,which) 2 | 3 | if (nargin<5) 4 | which=1:size(edges,1); 5 | end 6 | if (size(which,2)>size(which,1)) 7 | which=which'; 8 | end 9 | 10 | if (nargin<4) 11 | Zmax=0; 12 | end 13 | 14 | X=[coordinates(edges(which,1),1) coordinates(edges(which,2),1)]'; 15 | Y=[coordinates(edges(which,1),2) coordinates(edges(which,2),2)]'; 16 | if (size(coordinates,2)==2) 17 | plot3(X,Y,Zmax*ones(size(Y)),format,'LineWidth',0.5) 18 | else 19 | Z=[coordinates(edges(which,1),3) coordinates(edges(which,2),3)]'; 20 | plot3(X,Y,Z,format,'LineWidth',0.5) 21 | end 22 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/draw_vertices.m: -------------------------------------------------------------------------------- 1 | function draw_vertices(coordinates, vertices) 2 | if (nargin==1) 3 | vertices=1:size(coordinates,1); 4 | end 5 | if (size(vertices,2)>size(vertices,1)) 6 | vertices=vertices'; 7 | end 8 | 9 | plot(coordinates(vertices,1),coordinates(vertices,2),'o'); 10 | end 11 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_boundary_nodes.m: -------------------------------------------------------------------------------- 1 | function show_boundary_nodes(coordinates,dn,nn) 2 | 3 | if size(coordinates,2)==2 4 | scatter(coordinates(dn,1),coordinates(dn,2),25,'o','MarkerFaceColor', 'b') 5 | hold on 6 | scatter(coordinates(nn,1),coordinates(nn,2),50,'ro') 7 | hold off 8 | xlabel('x'); ylabel('y'); 9 | elseif size(coordinates,2)==3 10 | %plot_points([coordinates(nn,1),coordinates(nn,2),coordinates(nn,3)],'rx'); 11 | scatter3(coordinates(dn,1),coordinates(dn,2),coordinates(dn,3),25,'o', 'MarkerFaceColor', 'b') 12 | hold on 13 | scatter3(coordinates(nn,1),coordinates(nn,2),coordinates(nn,3),50, 'ro') 14 | hold off 15 | xlabel('x'); ylabel('y'); zlabel('z'); 16 | end 17 | end 18 | 19 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_constant_scalar.m: -------------------------------------------------------------------------------- 1 | function show_constant_scalar(constantValue,nodes2coord,elems2nodes,nodalDisplacement) 2 | 3 | if (nargin==4) 4 | if norm(nodalDisplacement)==0 5 | factor=1; 6 | else 7 | factor =10^(-round(log10(max(max(nodalDisplacement))))); 8 | end 9 | else 10 | nodalDisplacement=zeros(size(nodes2coord)); 11 | end 12 | 13 | X=nodes2coord(:,1)+nodalDisplacement(:,1); 14 | Y=nodes2coord(:,2)+nodalDisplacement(:,2); 15 | fill3(X(elems2nodes)',Y(elems2nodes)',kron(ones(1,size(elems2nodes,2)),constantValue)',kron(ones(1,size(elems2nodes,2)),constantValue)','FaceColor','interp','LineStyle','none'); 16 | 17 | 18 | 19 | end 20 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_constant_scalar_frame.asv: -------------------------------------------------------------------------------- 1 | function show_constant_scalar_frame(constantValue,elements,coordinates,nodalDisplacement) 2 | 3 | if (nargin==4) 4 | if norm(nodalDisplacement)==0 5 | factor=1; 6 | else 7 | factor =10^(-round(log10(max(max(nodalDisplacement))))); 8 | end 9 | else 10 | nodalDisplacement=zeros(size(coordinates)); 11 | end 12 | 13 | if size(coordinates,2)==2 14 | X=coordinates(:,1)+nodalDisplacement(:,1); 15 | Y=coordinates(:,2)+nodalDisplacement(:,2); 16 | 17 | XX=X(elements)'; 18 | YY=Y(elements)'; 19 | ZZ=kron(ones(1,size(elements,2)),constantValue)'; 20 | CC=ZZ; 21 | fill3(XX,YY,ZZ,CC,'FaceColor','interp','Linewidth',0.1); 22 | 23 | if size(coordinates,2)==3 24 | 25 | 26 | X=coordinates(:,1)+nodalDisplacement(:,1); 27 | Y=coordinates(:,2)+nodalDisplacement(:,2); 28 | Z=coordinates(:,3)+nodalDisplacement(:,3); 29 | 30 | elements=[elements(:,[1 2 3]); elements(:,[1 2 4]); elements(:,[2 3 4]); elements(:,[3 1 4])]; 31 | constant 32 | 33 | XX=X(elements)'; 34 | YY=Y(elements)'; 35 | ZZ=Z(elements)'; 36 | CC= 37 | 38 | fill3(X(elements)',Y(elements)',Z(elements)','FaceColor','interp','Linewidth',0.1); 39 | end 40 | 41 | 42 | 43 | end 44 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_constant_scalar_frame.m: -------------------------------------------------------------------------------- 1 | function show_constant_scalar_frame(constantValue,elements,coordinates,nodalDisplacement) 2 | 3 | if (nargin==4) 4 | if norm(nodalDisplacement)==0 5 | factor=1; 6 | else 7 | factor =10^(-round(log10(max(max(nodalDisplacement))))); 8 | end 9 | else 10 | nodalDisplacement=zeros(size(coordinates)); 11 | end 12 | 13 | if size(coordinates,2)==2 14 | X=coordinates(:,1)+nodalDisplacement(:,1); 15 | Y=coordinates(:,2)+nodalDisplacement(:,2); 16 | 17 | XX=X(elements)'; 18 | YY=Y(elements)'; 19 | ZZ=kron(ones(1,size(elements,2)),constantValue)'; 20 | CC=ZZ; 21 | fill3(XX,YY,ZZ,CC,'FaceColor','interp','Linewidth',0.1); 22 | 23 | if size(coordinates,2)==3 %3D only testing 24 | 25 | X=coordinates(:,1)+nodalDisplacement(:,1); 26 | Y=coordinates(:,2)+nodalDisplacement(:,2); 27 | Z=coordinates(:,3)+nodalDisplacement(:,3); 28 | 29 | elements=[elements(:,[1 2 3]); elements(:,[1 2 4]); elements(:,[2 3 4]); elements(:,[3 1 4])]; 30 | constantValue=[constantValue; constantValue; constantValue; constantValue]; 31 | 32 | XX=X(elements)'; 33 | YY=Y(elements)'; 34 | ZZ=Z(elements)'; 35 | CC=constantValue(elements)'; 36 | fill3(XX,YY,ZZ,CC,'FaceColor','interp','Linewidth',0.1); 37 | 38 | trimesh(elements,X,Y,Z); 39 | end 40 | 41 | 42 | 43 | end 44 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_edges.m: -------------------------------------------------------------------------------- 1 | function show_edges(edge2nodes,coordinates,which) 2 | %function: show_edges(edge,coordinates,whichelements) 3 | %requires: show_points 4 | %displays edges numbers at their middle point coordinates 5 | %if which are not provided, all are displayed 6 | 7 | if (nargin==2) 8 | %all elements will be displayed 9 | which=1:size(edge2nodes,1); 10 | elseif (size(which,2)>size(which,1)) 11 | which=which'; 12 | end 13 | 14 | middle_points=(coordinates(edge2nodes(:,1),:)+coordinates(edge2nodes(:,2),:))/2; 15 | if (size(coordinates,2)==3) 16 | %3D case 17 | show_points_blue(middle_points(which,1), middle_points(which,2),middle_points(which,3),which); 18 | else 19 | %2D case 20 | show_points_blue(middle_points(which,1), middle_points(which,2),0*middle_points(which,1),which); 21 | end 22 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_elements.m: -------------------------------------------------------------------------------- 1 | function show_elements(elements,coordinates,which) 2 | %function: show_elements(elements,coordinates,whichelements) 3 | %requires: show_points 4 | %displays element numbers at their middle point coordinates 5 | %if which are not provided, all are displayed 6 | 7 | if (nargin==2) 8 | %all elements will be displayed 9 | which=1:size(elements,1); 10 | elseif (size(which,2)>size(which,1)) 11 | which=which'; 12 | end 13 | 14 | if (size(coordinates,2)==3) 15 | %3D case 16 | middle_points=(coordinates(elements(:,1),:)+coordinates(elements(:,2),:)+coordinates(elements(:,3),:)+coordinates(elements(:,4),:))/4; 17 | show_points_red(middle_points(which,1), middle_points(which,2),middle_points(which,3),which); 18 | else 19 | %2D case 20 | middle_points=evaluate_elements_average(elements,coordinates); 21 | show_points_red(middle_points(which,1), middle_points(which,2),0*middle_points(which,1),which); 22 | end 23 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_mesh.m: -------------------------------------------------------------------------------- 1 | function show_mesh(elements,coordinates) 2 | if size(coordinates,2)==2 %2D objects 3 | %works for both triangles and rectangles 4 | X=reshape(coordinates(elements',1),size(elements,2),size(elements,1)); 5 | Y=reshape(coordinates(elements',2),size(elements,2),size(elements,1)); 6 | fill(X,Y,'w'); 7 | elseif size(coordinates,2)==3 %3D object 8 | if size(elements,2)==4 %tetrahedra 9 | tetramesh(elements,coordinates,'FaceAlpha',1,'FaceColor','white');%camorbit(20,0); 10 | end 11 | 12 | if size(elements,2)==8 %hexahedra 13 | faces1=elements(:,1:4); 14 | faces2=elements(:,5:8); 15 | faces3=elements(:,[1 4 8 5]); 16 | faces4=elements(:,[2 3 7 6]); 17 | faces5=elements(:,[1 2 6 5]); 18 | faces6=elements(:,[3 4 8 7]); 19 | 20 | faces=[faces1; faces2; faces3; faces4; faces5; faces6]; 21 | 22 | X=reshape(coordinates(faces',1),size(faces,2),size(faces,1)); 23 | Y=reshape(coordinates(faces',2),size(faces,2),size(faces,1)); 24 | Z=reshape(coordinates(faces',3),size(faces,2),size(faces,1)); 25 | 26 | fill3(X,Y,Z,[0.0 0.0 0.0],'FaceAlpha',1,'FaceColor','white'); 27 | end 28 | 29 | if size(elements,2)==3 % triangular faces 30 | faces=elements; 31 | 32 | X=reshape(coordinates(faces',1),size(faces,2),size(faces,1)); 33 | Y=reshape(coordinates(faces',2),size(faces,2),size(faces,1)); 34 | Z=reshape(coordinates(faces',3),size(faces,2),size(faces,1)); 35 | 36 | fill3(X,Y,Z,[0.3 0.3 0.9]); 37 | end 38 | 39 | end 40 | 41 | 42 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_nodal_scalar.m: -------------------------------------------------------------------------------- 1 | function show_nodal_scalar(nodalValue,elements,coordinates,nodalDisplacement) 2 | if nargin==3 3 | h=show_nodal_scalar_frame(nodalValue,elements,coordinates); 4 | set(h,'edgecolor','none') 5 | elseif nargin==4 6 | h=show_nodal_scalar_frame(nodalValue,elements,coordinates,nodalDisplacement); 7 | set(h,'edgecolor','none') 8 | end 9 | 10 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_nodal_scalar_frame.m: -------------------------------------------------------------------------------- 1 | function h=show_nodal_scalar_frame(nodalValue,elements,coordinates,nodalDisplacement) 2 | switch nargin, 3 | case 3, 4 | nodalDisplacement=0*coordinates; 5 | case {0, 1, 2} 6 | fprintf('missing parameters') 7 | end 8 | 9 | if size(coordinates,2)==2 10 | X=coordinates(:,1)+nodalDisplacement(:,1); 11 | Y=coordinates(:,2)+nodalDisplacement(:,2); 12 | 13 | h=trisurf(elements,X,Y,nodalValue,'FaceColor','interp'); 14 | 15 | %XX=X(elements)'; 16 | %YY=Y(elements)'; 17 | %ZZ=nodalValue(elements)'; 18 | %CC=ZZ; 19 | %fill3(XX,YY,ZZ,CC,'FaceColor','interp','Linewidth',0.1); 20 | elseif size(coordinates,2)==3 %3D only testing 21 | X=coordinates(:,1)+nodalDisplacement(:,1); 22 | Y=coordinates(:,2)+nodalDisplacement(:,2); 23 | Z=coordinates(:,3)+nodalDisplacement(:,3); 24 | 25 | elements=[elements(:,[1 2 3]); elements(:,[1 2 4]); elements(:,[2 3 4]); elements(:,[3 1 4])]; 26 | 27 | h=trisurf(elements,X,Y,Z,nodalValue,'FaceColor','interp'); 28 | 29 | %XX=X(elements)'; 30 | %YY=Y(elements)'; 31 | %ZZ=Z(elements)'; 32 | %CC=nodalValue(elements)'; 33 | %fill3(XX,YY,ZZ,CC,'FaceColor','interp','Linewidth',0.1); 34 | end 35 | 36 | %set(gcf,'renderer','zbuffer'); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_nodes.m: -------------------------------------------------------------------------------- 1 | function show_nodes(coordinates,dn,nn) 2 | 3 | if (nargin==1) 4 | dn=1:size(coordinates,1); 5 | nn=[]; 6 | end 7 | 8 | 9 | if size(coordinates,2)==2 10 | scatter(coordinates(dn,1),coordinates(dn,2),30,'o','MarkerFaceColor', 'b') 11 | hold on 12 | scatter(coordinates(nn,1),coordinates(nn,2),50,'ro') 13 | hold off 14 | xlabel('x'); ylabel('y'); 15 | elseif size(coordinates,2)==3 16 | %plot_points([coordinates(nn,1),coordinates(nn,2),coordinates(nn,3)],'rx'); 17 | scatter3(coordinates(dn,1),coordinates(dn,2),coordinates(dn,3),30,'o', 'MarkerFaceColor', 'b') 18 | hold on 19 | scatter3(coordinates(nn,1),coordinates(nn,2),coordinates(nn,3),50, 'ro') 20 | hold off 21 | xlabel('x'); ylabel('y'); zlabel('z'); 22 | end 23 | end 24 | 25 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_points.m: -------------------------------------------------------------------------------- 1 | function show_points(pointsX,pointsY,pointsZ,labels) 2 | if (size(labels,2)>size(labels,1)) 3 | labels=labels'; 4 | end 5 | text(pointsX, pointsY, pointsZ,int2str(labels), 'fontsize', 14, 'fontweight', 'bold'); 6 | 7 | %'BackgroundColor',[0 0 1] - blue color -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_points_blue.m: -------------------------------------------------------------------------------- 1 | function show_points_blue(pointsX,pointsY,pointsZ,labels) 2 | if (size(labels,2)>size(labels,1)) 3 | labels=labels'; 4 | end 5 | text(pointsX, pointsY, pointsZ,int2str(labels),'color','b','fontsize', 10, 'fontweight', 'bold'); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_points_red.m: -------------------------------------------------------------------------------- 1 | function show_points_red(pointsX,pointsY,pointsZ,labels) 2 | if (size(labels,2)>size(labels,1)) 3 | labels=labels'; 4 | end 5 | text(pointsX, pointsY, pointsZ,int2str(labels),'color','r','fontsize', 10, 'fontweight', 'bold'); -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_vertices.m: -------------------------------------------------------------------------------- 1 | function show_vertices(coordinates, vertices) 2 | if (nargin==1) 3 | vertices=1:size(coordinates,1); %all point will be displayed 4 | end 5 | if (size(vertices,2)>size(vertices,1)) 6 | vertices=vertices'; %transposing the vector 7 | end 8 | 9 | if size(coordinates,2)==2 10 | show_points(coordinates(vertices,1),coordinates(vertices,2),0*coordinates(vertices,2),vertices); %2D 11 | elseif size(coordinates,2)==3 12 | show_points(coordinates(vertices,1),coordinates(vertices,2),coordinates(vertices,3),vertices); % 3D 13 | end 14 | -------------------------------------------------------------------------------- /elasticity/3rd_party_elasticity_codes_for_testing/code_rv/library_visualization/show_vertices_red.m: -------------------------------------------------------------------------------- 1 | function show_vertices_red(coordinates, vertices) 2 | if (nargin==1) 3 | vertices=1:size(coordinates,1); 4 | end 5 | 6 | if (size(vertices,2)>size(vertices,1)) 7 | vertices=vertices'; 8 | end 9 | 10 | show_points_red(coordinates(vertices,1),coordinates(vertices,2),0*coordinates(vertices,2),vertices); %2D only modification 11 | end 12 | -------------------------------------------------------------------------------- /elasticity/add_paths.m: -------------------------------------------------------------------------------- 1 | 2 | % This script adds the absolute location of 3 | % the shared functions to the path 4 | 5 | path1 = cd; 6 | %cd .. 7 | path2 = cd; 8 | if ( isunix ) 9 | addpath(genpath([path2,'.'])); 10 | else 11 | addpath(genpath([path2,'.'])); 12 | end 13 | cd(path1) 14 | %clear all -------------------------------------------------------------------------------- /elasticity/comparison_assembly_P1_2D_elasticity.m: -------------------------------------------------------------------------------- 1 | clear level_size_P1 level_time_P1_CSV level_time_P1_RV 2 | 3 | % add_paths; 4 | addpath(genpath('3rd_party_elasticity_codes_for_testing'),'elasticity_2D'); 5 | 6 | levels=8; %maximum uniform refinement level 7 | 8 | %homogeneous material parameters 9 | young = 206900 ; % Young's modulus E 10 | poisson = 0.29 ; % Poisson's ratio nu 11 | 12 | lambda= young*poisson/((1+poisson)*(1-2*poisson)) ; %Lamme first parameter 13 | mu = young./(2*(1+poisson)) ; %Lamme second parameter 14 | 15 | bulkC = young./(3*(1-2*poisson)) ; % bulk modulus K 16 | shearC = mu ; % shear modulus G (equal to Lamme second parameter) 17 | 18 | demo=0; create_2D_mesh; %mesh for testing 19 | 20 | for level=0:levels 21 | %uniform refinement 22 | if (level>0) 23 | [coordinates,elements,dirichlet]=refinement_uniform(coordinates,elements,dirichlet); 24 | end 25 | 26 | figure(1); visualize_mesh; 27 | 28 | rows=numel(coordinates); 29 | level_size_P1(level+1)=rows; 30 | 31 | %stiffness matrix assembly - method 1 32 | fprintf('technique of Cermak, Sysala and Valdman:\n') 33 | tic; 34 | [Xi, WF] = quadrature_volume('P1'); % quadrature points and weights for volume integrals 35 | [HatP,DHatP1,DHatP2] = local_basis_volume('P1', Xi); % local basis functions and their derivatives for volume integrals 36 | n_e=size(elements',2); % number of elements 37 | n_q=length(WF); % number of quadratic points 38 | n_int = n_e*n_q ; % total number of integrations points 39 | shear =shearC*ones(1,n_int); bulk=bulkC*ones(1,n_int); 40 | K=elastic_stiffness_matrix(elements',coordinates',shear,bulk,DHatP1,DHatP2,WF); 41 | assembly_time=toc; 42 | level_time_P1_CSV(level+1)=assembly_time; 43 | 44 | rows=size(K,1); 45 | fprintf('level=%d, ', level); 46 | fprintf('time spent on K: %6.1e seconds, ',assembly_time(end)); 47 | fprintf('rows of matrix =%d ',rows); 48 | fprintf('\n'); 49 | 50 | %stiffness matrix assembly - method 2 51 | fprintf('technique of Rahman and Valdman: \n') 52 | tic; 53 | K=stiffness_matrixP1_2D_elasticity(elements,coordinates,lambda,mu); 54 | assembly_time=toc; 55 | level_time_P1_RV(level+1)=assembly_time; 56 | 57 | fprintf('level=%d, ', level); 58 | fprintf('time spent on K: %6.1e seconds, ',assembly_time(end)); 59 | fprintf('rows of matrix =%d ',rows); 60 | fprintf('\n'); 61 | 62 | fprintf('-----------------------------------------------\n') 63 | end 64 | 65 | % output information 66 | fprintf('\n') 67 | for level=0:levels 68 | fprintf('%d ', level); 69 | fprintf('& '); 70 | fprintf('%d ', level_size_P1(level+1)); 71 | fprintf('& '); 72 | fprintf('%2.2f ', level_time_P1_CSV(level+1)); 73 | fprintf('& '); 74 | fprintf('%2.2f ', level_time_P1_RV(level+1)); 75 | fprintf('\\\\'); 76 | fprintf('\n'); 77 | end 78 | 79 | 80 | rmpath(genpath('3rd_party_elasticity_codes_for_testing'),'elasticity_2D'); 81 | 82 | -------------------------------------------------------------------------------- /elasticity/comparison_assembly_P1_3D_elasticity.m: -------------------------------------------------------------------------------- 1 | clear rows level_size_P1 level_time_P1_CSV level_time_P1_RV 2 | 3 | % add_paths; 4 | addpath(genpath('3rd_party_elasticity_codes_for_testing'),'elasticity_3D'); 5 | 6 | levels=2; %maximum uniform refinement level 7 | 8 | %homogeneous material parameters 9 | young = 206900 ; % Young's modulus E 10 | poisson = 0.29 ; % Poisson's ratio nu 11 | 12 | lambda= young*poisson/((1+poisson)*(1-2*poisson)) ; %Lamme first parameter 13 | mu = young./(2*(1+poisson)) ; %Lamme second parameter 14 | 15 | bulkC = young./(3*(1-2*poisson)) ; % bulk modulus K 16 | shearC = mu ; % shear modulus G (equal to Lamme second parameter) 17 | 18 | %coarse mesh 19 | load mesh3D.mat; elements=elements3; clear elements3 20 | 21 | for level=0:levels 22 | %uniform refinement 23 | if (level>0) 24 | [coordinates,elements]=refinement_uniform3D(coordinates,elements); 25 | end 26 | 27 | figure(4); visualize_mesh; 28 | 29 | rows=numel(coordinates); 30 | level_size_P1(level+1)=rows; 31 | 32 | %stiffness matrix assembly - method 1 33 | fprintf('technique of Cermak, Sysala and Valdman:\n') 34 | tic; 35 | [Xi, WF] = quadrature_volume('P1'); % quadrature points and weights for volume integrals 36 | [HatP,DHatP1,DHatP2,DHatP3] = local_basis_volume('P1', Xi); % local basis functions and their derivatives for volume integrals 37 | n_e=size(elements',2); % number of elements 38 | n_q=length(WF); % number of quadratic points 39 | n_int = n_e*n_q ; % total number of integrations points 40 | shear =shearC*ones(1,n_int); bulk=bulkC*ones(1,n_int); 41 | [K,WEIGHT]=elastic_stiffness_matrix(elements',coordinates',shear,bulk,DHatP1,DHatP2,DHatP3,WF); 42 | assembly_time=toc; 43 | level_time_P1_CSV(level+1)=assembly_time; 44 | 45 | rows=size(K,1); 46 | fprintf('level=%d, ', level); 47 | fprintf('time spent on K: %6.1e seconds, ',assembly_time(end)); 48 | fprintf('rows of matrix =%d ',rows); 49 | fprintf('\n'); 50 | 51 | %stiffness matrix assembly - method 2 52 | fprintf('technique of Rahman and Valdman: \n') 53 | tic; 54 | K2=stiffness_matrixP1_3D_elasticity(elements,coordinates,lambda,mu); 55 | assembly_time=toc; 56 | level_time_P1_RV(level+1)=assembly_time; 57 | 58 | fprintf('level=%d, ', level); 59 | fprintf('time spent on K: %6.1e seconds, ',assembly_time(end)); 60 | fprintf('rows of matrix =%d ',rows); 61 | fprintf('\n'); 62 | 63 | fprintf('-----------------------------------------------\n') 64 | end 65 | 66 | % output information 67 | fprintf('\n') 68 | for level=0:levels 69 | fprintf('%d ', level); 70 | fprintf('& '); 71 | fprintf('%d ', level_size_P1(level+1)); 72 | fprintf('& '); 73 | fprintf('%2.2f ', level_time_P1_CSV(level+1)); 74 | fprintf('& '); 75 | fprintf('%2.2f ', level_time_P1_RV(level+1)); 76 | fprintf('\\\\'); 77 | fprintf('\n'); 78 | end 79 | 80 | rmpath(genpath('3rd_party_elasticity_codes_for_testing'),'elasticity_3D'); 81 | -------------------------------------------------------------------------------- /elasticity/comparison_fem_3D_elasticity.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | close all; 3 | 4 | % add_paths; 5 | addpath(genpath('3rd_party_elasticity_codes_for_testing'),'elasticity_3D'); 6 | 7 | fprintf('Benchmark from the article of J. Alberty, C. Carstensen, S. Funken, R. Klose: \n') 8 | figure(1); fem_lame3d; %running the modified code of Alberty, Carstensen, Funken, Klose 9 | 10 | fprintf('\n') 11 | 12 | fprintf('Benchmark from the article of J. Koko: \n') 13 | figure(2); demo_elas; %running the modified code of Koko 14 | 15 | rmpath(genpath('3rd_party_elasticity_codes_for_testing'),'elasticity_3D'); 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /elasticity/elasticity_2D/draw_displacement.m: -------------------------------------------------------------------------------- 1 | function draw_displacement(coord,elem,U,U_disp,elem_type,... 2 | size_xy,size_hole) 3 | 4 | % ========================================================================= 5 | % 6 | % This function depicts prescribed displacements, deformed and undeformed 7 | % shape of the body 8 | % 9 | % input data: 10 | % coord - coordinates of the nodes, size(coord)=(2,n_n) where n_n is a 11 | % number of nodes 12 | % elem - array containing numbers of nodes defining each element, 13 | % size(elem)=(n_p,n_e), n_e = number of elements 14 | % U - nodal displacements, size(U)=(2,n_n) 15 | % U_disp - prescribed displacements (e.g. total displacement or 16 | % displacements in x directions, etc.), size(U_disp)=(1,n_n) 17 | % elem_type - the type of finite elements; available choices: 18 | % 'P1', 'P2', 'Q1', 'Q2' 19 | % size_xy - size of the body in x and y direction (integer) 20 | % size_hole - size of the hole in the body (integer) 21 | % size_hole < size_xy 22 | % body=(0,size_xy) x(0,size_xy) \setminus 23 | % (0,size_hole)x(0,size_hole) 24 | % 25 | % ====================================================================== 26 | % 27 | 28 | figure; 29 | hold on; 30 | coord_aux = [coord;zeros(1,size(coord,2))] + [U;zeros(1,size(U,2))]; 31 | % displacements and deformed shape 32 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 33 | s = patch('Faces',elem(1:3,:)','Vertices',coord_aux',... 34 | 'FaceVertexCData',U_disp','FaceColor','interp','EdgeColor','none'); 35 | else 36 | s = patch('Faces',elem(1:4,:)','Vertices',coord_aux',... 37 | 'FaceVertexCData',U_disp','FaceColor','interp','EdgeColor','none'); 38 | end 39 | if ~isOctave 40 | alpha(s,.5); 41 | end 42 | colorbar; 43 | 44 | % undeformed shape of the body 45 | plot([size_hole,size_xy],[0,0]) 46 | plot([0,size_xy],[size_xy,size_xy]) 47 | plot([0,size_hole],[size_hole,size_hole]) 48 | plot([0,0],[size_hole,size_xy]) 49 | plot([size_hole,size_hole],[0,size_hole]) 50 | plot([size_xy,size_xy],[0,size_xy]) 51 | 52 | % 53 | box on 54 | view(2); % standard view ve 2D 55 | axis equal; % real ratios 56 | hold off; 57 | axis off; 58 | end -------------------------------------------------------------------------------- /elasticity/elasticity_2D/draw_mesh.m: -------------------------------------------------------------------------------- 1 | function draw_mesh(coord,elem,elem_type) 2 | 3 | % ========================================================================= 4 | % 5 | % This function draws mesh and nodal point on the surface of the body 6 | % 7 | % input data: 8 | % coord - coordinates of the nodes, size(coord)=(2,n_n) where n_n is a 9 | % number of nodes 10 | % elem - array containing numbers of nodes defining each element, 11 | % size(elem)=(n_p, n_e), n_e = number of elements 12 | % elem_type - the type of finite elements; available choices: 13 | % 'P1', 'P2', 'Q1', 'Q2' 14 | % 15 | % ====================================================================== 16 | % 17 | 18 | figure 19 | hold on 20 | coord_aux = [coord;zeros(1,size(coord,2))]; 21 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 22 | patch('Faces',elem(1:3,:)','Vertices',coord_aux','FaceVertexCData',... 23 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 24 | else 25 | patch('Faces',elem(1:4,:)','Vertices',coord_aux','FaceVertexCData',... 26 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 27 | end 28 | 29 | plot( coord(1,:),coord(2,:), 'b.', 'MarkerSize',10); 30 | axis equal; %real ratios 31 | view(2); %standard view in 2D 32 | hold off; 33 | axis off; 34 | end -------------------------------------------------------------------------------- /elasticity/elasticity_2D/elasticity_assembly_test.m: -------------------------------------------------------------------------------- 1 | % ========================================================================= 2 | % 3 | % This program triggers an assembly test for an elastic body. The 4 | % assembly time of the stiffness matrix is stored depending on a choice of 5 | % the finite elements and mesh density. 6 | % 7 | % ====================================================================== 8 | % 9 | 10 | % number of mesh levels 11 | levels=4; 12 | 13 | % P1 elements 14 | fprintf('P1 elements: \n') 15 | level_time_P1=zeros(1,levels); 16 | level_size_P1=zeros(1,levels); 17 | for level=0:levels 18 | [level_time_P1(level+1),level_size_P1(level+1)]=elasticity_fem('P1',level,level==0); 19 | end 20 | fprintf('\n') 21 | 22 | % P2 elements 23 | fprintf('P2 elements: \n') 24 | level_time_P2=zeros(1,levels); 25 | level_size_P2=zeros(1,levels); 26 | for level=0:levels 27 | [level_time_P2(level+1),level_size_P2(level+1)]=elasticity_fem('P2',level,level==0); 28 | end 29 | fprintf('\n') 30 | 31 | % Q1 elements 32 | fprintf('Q1 elements: \n') 33 | level_time_Q1=zeros(1,levels); 34 | level_size_Q1=zeros(1,levels); 35 | for level=0:levels 36 | [level_time_Q1(level+1),level_size_Q1(level+1)]=elasticity_fem('Q1',level,level==0); 37 | end 38 | fprintf('\n') 39 | 40 | % Q2 elements 41 | fprintf('Q2 elements: \n') 42 | level_time_Q2=zeros(1,levels); 43 | level_size_Q2=zeros(1,levels); 44 | for level=0:levels 45 | [level_time_Q2(level+1),level_size_Q2(level+1)]=elasticity_fem('Q2',level,level==0); 46 | end 47 | 48 | % output information 49 | fprintf('\n') 50 | for level=0:levels 51 | fprintf('%d ', level); 52 | fprintf('& '); 53 | fprintf('%d ', level_size_P1(level+1)); 54 | fprintf('& '); 55 | fprintf('%d ', level_size_P2(level+1)); 56 | fprintf('& '); 57 | fprintf('%d ', level_size_Q1(level+1)); 58 | fprintf('& '); 59 | fprintf('%d ', level_size_Q2(level+1)); 60 | fprintf('& '); 61 | fprintf('%2.2f ', level_time_P1(level+1)); 62 | fprintf('& '); 63 | fprintf('%2.2f ', level_time_P2(level+1)); 64 | fprintf('& '); 65 | fprintf('%2.2f ', level_time_Q1(level+1)); 66 | fprintf('& '); 67 | fprintf('%2.2f ', level_time_Q2(level+1)); 68 | fprintf('\\\\'); 69 | fprintf('\n'); 70 | end -------------------------------------------------------------------------------- /elasticity/elasticity_2D/isOctave.m: -------------------------------------------------------------------------------- 1 | function retval = isOctave() 2 | persistent cacheval; % speeds up repeated calls 3 | 4 | if isempty (cacheval) 5 | cacheval = (exist ('OCTAVE_VERSION', 'builtin') > 0); 6 | end 7 | 8 | retval = cacheval; 9 | end -------------------------------------------------------------------------------- /elasticity/elasticity_2D/local_basis_surface.m: -------------------------------------------------------------------------------- 1 | function [HatP_s,DHatP1_s] = local_basis_surface(elem_type, Xi_s) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function evaluates local basis functions on a surface and their 5 | % derivatives at prescribed quadrature points depending on a chosen 6 | % finite elements. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % Xi_s - coordinates of the quadrature points, size(Xi_s)=(1,n_q_s) 11 | % 12 | % output data: 13 | % HatP_s - values of basis functions at the quadrature points, 14 | % size(HatP_s)=(n_p_s,n_q_s) 15 | % DHatP1_s - derivatives of basis functions at the quadrature points 16 | % in the direction xi_1, size(DHatP1_s)=(n_p_s,n_q_s) 17 | % n_p_s - number of basis functions on the surface 18 | % n_q_s - number of integration points within the surface 19 | %-------------------------------------------------------------------------- 20 | 21 | xi = Xi_s(1,:); 22 | 23 | switch(elem_type) 24 | case {'P1','Q1'} 25 | % - the reference line with coordinates: 26 | % -1, 1 27 | % - n_p_s=2, n_q_s=length(xi_1) 28 | HatP_s = (1/2)*[1-xi; 1+xi] ; 29 | DHatP1_s = [-1/2; 1/2]; 30 | 31 | case {'P2','Q2'} 32 | % - the reference line with coordinates: 33 | % -1, 1 34 | % - coordinates of midpoint: 35 | % 0 36 | % - n_p_s=3, n_q_s=length(xi_1) 37 | HatP_s = [xi.*(xi-1)/2; xi.*(xi+1)/2; (xi+1).*(1-xi)] ; 38 | DHatP1_s = [ xi-1/2; xi+1/2; -2*xi]; 39 | 40 | otherwise; disp('Bad choise of element type'); 41 | end 42 | -------------------------------------------------------------------------------- /elasticity/elasticity_2D/local_basis_volume.m: -------------------------------------------------------------------------------- 1 | function [HatP,DHatP1,DHatP2] = local_basis_volume(elem_type, Xi) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function evaluates local basis functions and their derivatives at 5 | % prescribed quadrature points depending on a chosen finite elements. 6 | % 7 | % input data: 8 | % elem_type - the type of Lagrange finite elements 9 | % Xi - coordinates of the quadrature points, size(Xi)=(2,n_q) 10 | % 11 | % output data: 12 | % HatP - values of basis functions at the quadrature points, 13 | % size(HatP)=(n_p,n_q) 14 | % DHatP1 - derivatives of basis functions at the quadrature points 15 | % in the direction xi_1, size(DHatP1)=(n_p,n_q) 16 | % DHatP2 - derivatives of basis functions at the quadrature points 17 | % in the direction xi_2, size(DHatP2)=(n_p,n_q) 18 | % n_p - number of basis functions 19 | % n_q - number of integration points within one element 20 | %-------------------------------------------------------------------------- 21 | 22 | xi_1 = Xi(1,:); xi_2 = Xi(2,:); 23 | 24 | switch(elem_type) 25 | case 'P1' 26 | % - the reference triangle with coordinates: 27 | % [0,0], [1,0], [0,1] 28 | % - n_p=3, n_q=length(xi_1) 29 | HatP = [1-xi_1-xi_2; xi_1; xi_2] ; 30 | DHatP1 = [ -1; 1; 0]; 31 | DHatP2 = [ -1; 0; 1]; 32 | 33 | case 'P2' 34 | % - the reference triangle with coordinates: 35 | % [0,0], [1,0], [0,1] 36 | % - coordinates of midpoints: 37 | % [1/2,1/2], [0,1/2], [1/2,0], 38 | % - n_p=6, n_q=length(xi_1) 39 | % - barycentric coordinates: xi_0, xi_1, xi_2, where 40 | xi_0 = 1-xi_1-xi_2; 41 | n_q = length(xi_1); 42 | HatP = [ xi_0.*(2*xi_0-1); xi_1.*(2*xi_1-1); xi_2.*(2*xi_2-1); 43 | 4*xi_1.*xi_2; 4*xi_0.*xi_2; 4*xi_0.*xi_1 ]; 44 | DHatP1 = [ -4*xi_0+1; 4*xi_1-1; zeros(1,n_q); 45 | 4*xi_2; -4*xi_2; 4*(xi_0-xi_1) ]; 46 | DHatP2 = [ -4*xi_0+1; zeros(1,n_q); 4*xi_2-1; 47 | 4*xi_1; 4*(xi_0-xi_2); -4*xi_1 ]; 48 | 49 | case 'Q1' 50 | % - the reference square with coordinates: 51 | % [-1,-1], [1,-1], [1,1], [-1,1] 52 | % - n_p_s=4, n_q_s=length(xi_1) 53 | HatP=[(1-xi_1).*(1-xi_2)/4; (1+xi_1).*(1-xi_2)/4; 54 | (1+xi_1).*(1+xi_2)/4; (1-xi_1).*(1+xi_2)/4 ]; 55 | DHatP1 = [-(1-xi_2)/4; (1-xi_2)/4; 56 | (1+xi_2)/4; -(1+xi_2)/4 ]; 57 | DHatP2 = [-(1-xi_1)/4; -(1+xi_1)/4; 58 | (1+xi_1)/4; (1-xi_1)/4 ]; 59 | 60 | case 'Q2' 61 | % - the reference square with coordinates: 62 | % [-1,-1], [1,-1], [1,1], [-1,1] 63 | % - coordinates of midpoints: 64 | % [0,-1], [1,0], [0,1], [-1,0] 65 | % - n_p_s=8, n_q_s=length(xi_1) 66 | HatP = [ (1-xi_1).*(1-xi_2).*(-1-xi_1-xi_2)/4; 67 | (1+xi_1).*(1-xi_2).*(-1+xi_1-xi_2)/4; 68 | (1+xi_1).*(1+xi_2).*(-1+xi_1+xi_2)/4; 69 | (1-xi_1).*(1+xi_2).*(-1-xi_1+xi_2)/4; 70 | (1-xi_1.^2).*(1-xi_2)/2; 71 | (1+xi_1).*(1-xi_2.^2)/2; 72 | (1-xi_1.^2).*(1+xi_2)/2; 73 | (1-xi_1).*(1-xi_2.^2)/2 ]; 74 | 75 | DHatP1 = [ (1-xi_2).*(2*xi_1+xi_2)/4; 76 | (1-xi_2).*(2*xi_1-xi_2)/4; 77 | (1+xi_2).*(2*xi_1+xi_2)/4; 78 | (1+xi_2).*(2*xi_1-xi_2)/4; 79 | -xi_1.*(1-xi_2); 80 | (1-xi_2.^2)/2; 81 | -xi_1.*(1+xi_2); 82 | -(1-xi_2.^2)/2 ]; 83 | 84 | DHatP2 = [ (1-xi_1).*( xi_1+2*xi_2)/4; 85 | (1+xi_1).*(-xi_1+2*xi_2)/4; 86 | (1+xi_1).*( xi_1+2*xi_2)/4; 87 | (1-xi_1).*(-xi_1+2*xi_2)/4; 88 | -(1-xi_1.^2)/2; 89 | -(1+xi_1).*xi_2; 90 | (1-xi_1.^2)/2; 91 | -(1-xi_1).*xi_2 ]; 92 | 93 | otherwise; disp('Bad choise of element type'); 94 | end 95 | -------------------------------------------------------------------------------- /elasticity/elasticity_2D/quadrature_surface.m: -------------------------------------------------------------------------------- 1 | function [Xi_s, WF_s] = quadrature_surface(elem_type) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function specifies a numerical quadrature for surface integration, 5 | % depending on a chosen finite element. The quadratures suggested 6 | % below can be simply replaced by another ones. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % 11 | % output data: 12 | % Xi_s - local coordinates of quadrature points, size(Xi_s)=(1,n_q_s) 13 | % WF_s - weight factors, size(WF_s)=(1,n_q_s) 14 | %-------------------------------------------------------------------------- 15 | 16 | switch(elem_type) 17 | 18 | case {'P1','Q1'} 19 | % - surface is created by the reference line with coordinates: 20 | % -1, 1 21 | % - 1-point quadrature rule, i.e., n_q_s=1 22 | Xi_s=0; WF_s=2; 23 | 24 | case {'P2','Q2'} 25 | % - surface is created by the reference line with coordinates: 26 | % -1, 1 27 | % - 2-point quadrature rule, i.e., n_q_s=2 28 | pt = 1/sqrt(3); 29 | Xi_s=[-pt,pt]; 30 | WF_s=[1,1]; 31 | 32 | otherwise; disp('Bad choise of element type'); 33 | end 34 | -------------------------------------------------------------------------------- /elasticity/elasticity_2D/quadrature_volume.m: -------------------------------------------------------------------------------- 1 | function [Xi, WF] = quadrature_volume(elem_type) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function specifies a numerical quadrature for volume integration, 5 | % depending on a chosen finite element. The quadratures suggested 6 | % below can be simply replaced by another ones. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % 11 | % output data: 12 | % Xi - local coordinates of quadrature points, size(Xi)=(2,n_q) 13 | % WF - weight factors, size(WF)=(1,n_q) 14 | %-------------------------------------------------------------------------- 15 | 16 | switch(elem_type) 17 | 18 | case 'P1' 19 | % - the reference triangle with coordinates: 20 | % [0,0], [1,0], [0,1] 21 | % - 1-point quadrature rule, i.e., n_q=1 22 | Xi=[1/3; 1/3]; WF=1/2; 23 | 24 | case 'P2' 25 | % - the reference triangle with coordinates: 26 | % [0,0], [1,0], [0,1] 27 | % - 7-point quadrature rule, i.e., n_q=7 28 | Xi=[0.1012865073235, 0.7974269853531, 0.1012865073235, ... 29 | 0.4701420641051, 0.4701420641051, 0.0597158717898, 1/3; 30 | 0.1012865073235, 0.1012865073235, 0.7974269853531, ... 31 | 0.0597158717898, 0.4701420641051, 0.4701420641051, 1/3]; 32 | WF=[0.1259391805448, 0.1259391805448, 0.1259391805448, ... 33 | 0.1323941527885, 0.1323941527885, 0.1323941527885, 0.225]/2; 34 | 35 | case 'Q1' 36 | % - the reference cube with coordinates: 37 | % [-1,-1], [1,-1], [1,1], [-1,1] 38 | % - (2x2)-point quadrature rule, i.e., n_q=4 39 | pt = 1/sqrt(3); 40 | Xi=[-pt,-pt, pt, pt 41 | -pt, pt,-pt, pt]; 42 | WF=[1,1,1,1]; 43 | 44 | case 'Q2' 45 | % - the reference cube with coordinates: 46 | % [-1,-1], [1,-1], [1,1], [-1,1] 47 | % - (3x3)-point quadrature rule, i.e., n_q=9 48 | pt = sqrt(3/5); 49 | Xi=[-pt, pt, pt, -pt, 0, pt, 0, -pt, 0 50 | -pt, -pt, pt, pt, -pt, 0, pt, 0, 0]; 51 | WF=[25/81 25/81 25/81 25/81 40/81 40/81 40/81 40/81 64/81]; 52 | 53 | otherwise; disp('Bad choice of element type'); 54 | end 55 | -------------------------------------------------------------------------------- /elasticity/elasticity_2D/vector_traction.m: -------------------------------------------------------------------------------- 1 | function f_t = vector_traction(ELEM_s,COORD,f_t_int,HatP_s,DHatP1_s,WF_s) 2 | 3 | % ========================================================================= 4 | % 5 | % Assembling of the vector of traction forces acting on the upper side of 6 | % the 2D body 7 | % 8 | % output: 9 | % f_t - vector of traction forces, size(f_V)=(2,n_n), where n_n is 10 | % the number of nodes 11 | % 12 | % input data: 13 | % ELEM_s - to indicate nodes belonging to each surface element 14 | % size(ELEM_s)=(n_p_s,n_e_s) where n_e_s is a number of 15 | % surface elements n_p_s is a number of the nodes within one 16 | % surface element 17 | % COORD - coordinates of the nodes, size(COORD)=(2,n_n) 18 | % f_t_int - values of traction forces at integration points 19 | % size(f_t_int)=(2,n_int_s), where n_int_s=n_e_s*n_q_s is a 20 | % number of surface integration points and n_q_s is a number 21 | % of quadrature points on the surface 22 | % HatP_s - values of the surface basis functions at quadrature points 23 | % DHatP1_s - xi_1-derivatives of the surface basis functions at q. p. 24 | % size(HatP_s)=size(DHatP1_s)=(n_p_s,n_q_s) 25 | % WF_s - weight factors at surface quadrature points, 26 | % size(WF)=(1,n_q_s) 27 | % 28 | % ========================================================================= 29 | 30 | % 31 | % Auxilliary notation 32 | % 33 | 34 | n_n=size(COORD,2); % number of nodes including midpoints 35 | n_e_s=size(ELEM_s,2); % number of surface elements 36 | n_p_s=size(ELEM_s,1); % number of nodes within one surface element 37 | n_q_s=length(WF_s); % number of quadrature points on a surface element 38 | n_int_s=n_e_s*n_q_s ; % number of integration points on the surface 39 | % (on the upper side of the body) 40 | 41 | % 42 | % Jacobians and their determinants at surface integration points 43 | % 44 | 45 | % extension of the input arrays HatP_s,DHatP1_s by replication 46 | % size(HatPhi_s)=size(DHatPhi1_s)=(n_p_s,n_int_s) 47 | DHatPhi1_s=repmat(DHatP1_s,1,n_e_s); 48 | HatPhi_s=repmat(HatP_s,1,n_e_s) ; 49 | 50 | % coordinates of nodes defining each surface element 51 | % size(COORDs1)=(n_p_s,n_e_s) 52 | COORDs1=reshape(COORD(1,ELEM_s(:)),n_p_s,n_e_s); 53 | 54 | % coordinates of nodes around each surface integration point 55 | % size(COORDint1)=(n_p_s,n_int_s) 56 | COORDint1=kron(COORDs1,ones(1,n_q_s)); 57 | 58 | % components of the Jacobians: size=(1,n_int_s) 59 | J11=sum(COORDint1.*DHatPhi1_s); 60 | 61 | % determinant of the Jacobian: size=(1,n_int_s) 62 | DET_s=abs(J11); 63 | 64 | % weight coefficients: size(WEIGHT)=(1,n_int_s) 65 | WEIGHT_s = DET_s.*repmat(WF_s,1,n_e_s); 66 | 67 | % 68 | % Assembling of the vector of traction forces, size(f_V)=(2,n_n) 69 | % 70 | 71 | % auxilliary values at surface integration points, 72 | % size(vF1)=size(vF2)=(n_p_s,n_int_s) 73 | vF1 = HatPhi_s.*(ones(n_p_s,1)*(WEIGHT_s.*f_t_int(1,:))); 74 | vF2 = HatPhi_s.*(ones(n_p_s,1)*(WEIGHT_s.*f_t_int(2,:))); 75 | % row and column indices, size(iF)=size(jF)=(n_p_s,n_int_s) 76 | iF = ones(n_p_s,n_int_s); 77 | jF = kron(ELEM_s,ones(1,n_q_s)); 78 | % the asssembling by using the sparse command - values v for duplicate 79 | % doubles i,j are automatically added together 80 | f_t = [ sparse(iF(:), jF(:), vF1(:), 1, n_n); 81 | sparse(iF(:), jF(:), vF2(:), 1, n_n) ]; 82 | 83 | end -------------------------------------------------------------------------------- /elasticity/elasticity_2D/vector_volume.m: -------------------------------------------------------------------------------- 1 | % 2 | function f_V=vector_volume(ELEM,COORD,f_V_int,HatP,WEIGHT) 3 | 4 | % ====================================================================== 5 | % 6 | % Assembling of the vector of volume forces 7 | % 8 | % output: 9 | % f_V - vector of volume forces, size(f_V)=(2,n_n) where n_n is 10 | % the number of nodes 11 | % 12 | % input data: 13 | % ELEM - to indicate nodes belonging to each element 14 | % size(ELEM)=(n_p,n_e) where n_e is a number of elements 15 | % and n_p is a number of the nodes within one element 16 | % COORD - coordinates of the nodes, size(COORD)=(2,n_n) 17 | % f_V_int - values of volume forces at integration points 18 | % size(f_V_int)=(2,n_int), where n_int=n_e*n_q is a number 19 | % of integration points, n_q is a number of quadrature points 20 | % HatP - values of the basis functions at quadrature points 21 | % size(HatP))=(n_p,n_q) 22 | % WEIGHT - weight coefficients, size(WEIGHT)=(1,n_int) 23 | % 24 | % ========================================================================= 25 | 26 | % 27 | % Auxilliary notation 28 | % 29 | n_n=size(COORD,2); % number of nodes 30 | n_e=size(ELEM,2); % number of elements 31 | n_p=size(ELEM,1); % number of vertices per element 32 | n_q=size(HatP,2); % number of quadratic points 33 | n_int = n_e*n_q ; % total number of integrations points 34 | 35 | % extension of the input array HatP by replication 36 | % size(HatPhi)=(n_p,n_int) 37 | HatPhi=repmat(HatP,1,n_e); 38 | 39 | % 40 | % Assembling of the vector of volume forces, size(f_V)=(2,n_n) 41 | % 42 | % values at integration points, size(vF1)=size(vF2)=(n_p,n_int) 43 | vF1 = HatPhi.*(ones(n_p,1)*(WEIGHT.*f_V_int(1,:))); 44 | vF2 = HatPhi.*(ones(n_p,1)*(WEIGHT.*f_V_int(2,:))); 45 | % row and column indices, size(iF)=size(jF)=(n_p,n_int) 46 | iF = ones(n_p,n_int); 47 | jF = kron(ELEM,ones(1,n_q)); 48 | % the asssembling by using the sparse command - values v for duplicate 49 | % doubles i,j are automatically added together 50 | f_V = [ sparse(iF(:), jF(:), vF1(:), 1, n_n); 51 | sparse(iF(:), jF(:), vF2(:), 1, n_n) ]; 52 | end 53 | 54 | -------------------------------------------------------------------------------- /elasticity/elasticity_3D/draw_displacement.m: -------------------------------------------------------------------------------- 1 | function draw_displacement(coord,surf,U,U_disp,elem_type,... 2 | size_xy,size_z,size_hole) 3 | 4 | % ========================================================================= 5 | % 6 | % This function depicts prescribed displacements, deformed and undeformed 7 | % shape of the body 8 | % 9 | % input data: 10 | % coord - coordinates of the nodes, size(coord)=(3,n_n) where n_n is a 11 | % number of nodes 12 | % surf - array containing numbers of nodes defining eachsurface element, 13 | % size(surf)=(n_p,n_s), n_s = number of surface elements 14 | % U - nodal displacements, size(U)=(3,n_n) 15 | % U_disp - prescribed displacements (e.g. total displacement or 16 | % displacements in x directions, etc.), size(U_disp)=(1,n_n) 17 | % elem_type - the type of finite elements; available choices: 18 | % 'P1', 'P2', 'Q1', 'Q2' 19 | % size_xy - size of the body in x and y direction (integer) 20 | % size_z - size of the body in z-direction (integer) 21 | % size_hole - size of the hole in the body (integer) 22 | % size_hole < size_xy 23 | % body=(0,size_xy) x(0,size_xy) x(0,size_z)\setminus 24 | % (0,size_hole)x(0,size_hole)x(0,size_z) 25 | % 26 | % ====================================================================== 27 | % 28 | 29 | figure; 30 | hold on; 31 | 32 | % displacements and deformed shape 33 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 34 | s = patch('Faces',surf(1:3,:)','Vertices',coord'+U',... 35 | 'FaceVertexCData',U_disp','FaceColor','interp','EdgeColor','none'); 36 | else 37 | s = patch('Faces',surf(1:4,:)','Vertices',coord'+U',... 38 | 'FaceVertexCData',U_disp','FaceColor','interp','EdgeColor','none'); 39 | end 40 | if ~isOctave 41 | alpha(s,.5); 42 | end 43 | colorbar; 44 | 45 | % undeformed shape of the body 46 | plot3([size_hole,size_xy],[0,0],[0,0]) 47 | plot3([size_hole,size_xy],[0,0],[size_z,size_z]) 48 | plot3([0,size_xy],[size_xy,size_xy],[0,0]) 49 | plot3([0,size_xy],[size_xy,size_xy],[size_z,size_z]) 50 | plot3([0,size_hole],[size_hole,size_hole],[0,0]) 51 | plot3([0,size_hole],[size_hole,size_hole],[size_z,size_z]) 52 | plot3([0,0],[size_hole,size_xy],[0,0]) 53 | plot3([0,0],[size_hole,size_xy],[size_z,size_z]) 54 | plot3([size_hole,size_hole],[0,size_hole],[0,0]) 55 | plot3([size_hole,size_hole],[0,size_hole],[size_z,size_z]) 56 | plot3([size_xy,size_xy],[0,size_xy],[0,0]) 57 | plot3([size_xy,size_xy],[0,size_xy],[size_z,size_z]) 58 | plot3([0,0],[size_hole,size_hole],[0,size_z]) 59 | plot3([0,0],[size_xy,size_xy],[0,size_z]) 60 | plot3([size_hole,size_hole],[0,0],[0,size_z]) 61 | plot3([size_hole,size_hole],[size_hole,size_hole],[0,size_z]) 62 | plot3([size_xy,size_xy],[0,0],[0,size_z]) 63 | plot3([size_xy,size_xy],[size_xy,size_xy],[0,size_z]) 64 | 65 | % 66 | box on 67 | view(3); % standard view ve 3D 68 | axis equal; % real ratios 69 | hold off; 70 | axis off; 71 | end -------------------------------------------------------------------------------- /elasticity/elasticity_3D/draw_mesh.m: -------------------------------------------------------------------------------- 1 | function draw_mesh(coord,surf,elem_type) 2 | 3 | % ========================================================================= 4 | % 5 | % This function draws mesh and nodal point on the surface of the body 6 | % 7 | % input data: 8 | % coord - coordinates of the nodes, size(coord)=(3,n_n) where n_n is a 9 | % number of nodes 10 | % surf - array containing numbers of nodes defining each surface element, 11 | % size(surf)=(n_p,n_s), n_s = number of surface elements 12 | % elem_type - the type of finite elements; available choices: 13 | % 'P1', 'P2', 'Q1', 'Q2' 14 | % 15 | % ====================================================================== 16 | % 17 | 18 | figure 19 | hold on 20 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 21 | patch('Faces',surf(1:3,:)','Vertices',coord','FaceVertexCData',... 22 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 23 | else 24 | patch('Faces',surf(1:4,:)','Vertices',coord','FaceVertexCData',... 25 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 26 | end 27 | ind=unique(surf(:)); 28 | plot3( coord(1,ind),coord(2,ind),coord(3,ind), 'b.', 'MarkerSize',10); 29 | axis equal; % real ratios 30 | view(3); % standard view ve 3D 31 | hold off; 32 | axis off; 33 | end -------------------------------------------------------------------------------- /elasticity/elasticity_3D/elasticity_assembly_test.m: -------------------------------------------------------------------------------- 1 | % ========================================================================= 2 | % 3 | % This program triggers an assembly test for an elastic body. The 4 | % assembly time of the stiffness matrix is stored depending on a choice of 5 | % the finite elements and mesh density. 6 | % 7 | % ====================================================================== 8 | % 9 | 10 | % number of mesh levels 11 | levels=1; 12 | 13 | % P1 elements 14 | fprintf('P1 elements: \n') 15 | level_time_P1=zeros(1,levels); 16 | level_size_P1=zeros(1,levels); 17 | for level=0:levels 18 | [level_time_P1(level+1),level_size_P1(level+1)]=elasticity_fem('P1',level,level==0); 19 | end 20 | fprintf('\n') 21 | 22 | % P2 elements 23 | fprintf('P2 elements: \n') 24 | level_time_P2=zeros(1,levels); 25 | level_size_P2=zeros(1,levels); 26 | for level=0:levels 27 | [level_time_P2(level+1),level_size_P2(level+1)]=elasticity_fem('P2',level,level==0); 28 | end 29 | fprintf('\n') 30 | 31 | % Q1 elements 32 | fprintf('Q1 elements: \n') 33 | level_time_Q1=zeros(1,levels); 34 | level_size_Q1=zeros(1,levels); 35 | for level=0:levels 36 | [level_time_Q1(level+1),level_size_Q1(level+1)]=elasticity_fem('Q1',level,level==0); 37 | end 38 | fprintf('\n') 39 | 40 | % Q2 elements 41 | fprintf('Q2 elements: \n') 42 | level_time_Q2=zeros(1,levels); 43 | level_size_Q2=zeros(1,levels); 44 | for level=0:levels 45 | [level_time_Q2(level+1),level_size_Q2(level+1)]=elasticity_fem('Q2',level,level==0); 46 | end 47 | 48 | % output information 49 | fprintf('\n') 50 | for level=0:levels 51 | fprintf('%d ', level); 52 | fprintf('& '); 53 | fprintf('%d ', level_size_P1(level+1)); 54 | fprintf('& '); 55 | fprintf('%d ', level_size_P2(level+1)); 56 | fprintf('& '); 57 | fprintf('%d ', level_size_Q1(level+1)); 58 | fprintf('& '); 59 | fprintf('%d ', level_size_Q2(level+1)); 60 | fprintf('& '); 61 | fprintf('%2.2f ', level_time_P1(level+1)); 62 | fprintf('& '); 63 | fprintf('%2.2f ', level_time_P2(level+1)); 64 | fprintf('& '); 65 | fprintf('%2.2f ', level_time_Q1(level+1)); 66 | fprintf('& '); 67 | fprintf('%2.2f ', level_time_Q2(level+1)); 68 | fprintf('\\\\'); 69 | fprintf('\n'); 70 | end -------------------------------------------------------------------------------- /elasticity/elasticity_3D/isOctave.m: -------------------------------------------------------------------------------- 1 | function retval = isOctave() 2 | persistent cacheval; % speeds up repeated calls 3 | 4 | if isempty (cacheval) 5 | cacheval = (exist ('OCTAVE_VERSION', 'builtin') > 0); 6 | end 7 | 8 | retval = cacheval; 9 | end -------------------------------------------------------------------------------- /elasticity/elasticity_3D/quadrature_surface.m: -------------------------------------------------------------------------------- 1 | function [Xi_s, WF_s] = quadrature_surface(elem_type) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function specifies a numerical quadrature for surface integration, 5 | % depending on a chosen finite element. The quadratures suggested 6 | % below can be simply replaced by another ones. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % 11 | % output data: 12 | % Xi_s - local coordinates of quadrature points, size(Xi_s)=(2,n_q_s) 13 | % WF_s - weight factors, size(WF_s)=(1,n_q_s) 14 | %-------------------------------------------------------------------------- 15 | 16 | switch(elem_type) 17 | 18 | case 'P1' 19 | % - surface is created by the reference triangle with coordinates: 20 | % [0,0], [1,0], [0,1] 21 | % - 1-point quadrature rule, i.e., n_q_s=1 22 | Xi_s=[1/3; 1/3]; WF_s=1/2; 23 | 24 | case 'P2' 25 | % - surface is created by the reference triangle with coordinates: 26 | % [0,0], [1,0], [0,1] 27 | % - 3-point quadrature rule, i.e., n_q_s=3 28 | Xi_s=[1/6, 1/6, 2/3 29 | 1/6, 2/3, 1/6]; 30 | WF_s=[1/6, 1/6, 1/6]; 31 | 32 | case 'Q1' 33 | % - surface is created by the reference square with coordinates: 34 | % [-1,-1], [1,-1], [1,1], [-1,1] 35 | % - (2x2)-point quadrature rule, i.e., n_q_s=4 36 | pt = 1/sqrt(3); 37 | Xi_s=[-pt,-pt, pt, pt 38 | -pt, pt,-pt, pt]; 39 | WF_s=[1,1,1,1]; 40 | 41 | case 'Q2' 42 | % - surface is created by the reference square with coordinates: 43 | % [-1,-1], [1,-1], [1,1], [-1,1] 44 | % - (2x2)-point quadrature rule, i.e., n_q_s=4 45 | pt = 1/sqrt(3); 46 | Xi_s=[-pt,-pt, pt, pt 47 | -pt, pt,-pt, pt]; 48 | WF_s=[1,1,1,1]; 49 | 50 | otherwise; disp('Bad choise of element type'); 51 | end 52 | -------------------------------------------------------------------------------- /elasticity/elasticity_3D/quadrature_volume.m: -------------------------------------------------------------------------------- 1 | function [Xi, WF] = quadrature_volume(elem_type) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function specifies a numerical quadrature for volume integration, 5 | % depending on a chosen finite element. The quadratures suggested 6 | % below can be simply replaced by another ones. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % 11 | % output data: 12 | % Xi - local coordinates of quadrature points, size(Xi)=(3,n_q) 13 | % WF - weight factors, size(WF)=(1,n_q) 14 | %-------------------------------------------------------------------------- 15 | 16 | switch(elem_type) 17 | 18 | case 'P1' 19 | % - the reference tetrahedron with coordinates: 20 | % [0,0,0], [1,0,0], [0,1,0], [0,0,1] 21 | % - 1-point quadrature rule, i.e., n_q=1 22 | Xi=[1/4; 1/4; 1/4]; WF=1/6; 23 | 24 | case 'P2' 25 | % - the reference tetrahedron with coordinates: 26 | % [0,0,0], [1,0,0], [0,1,0], [0,0,1] 27 | % - 11-point quadrature rule, i.e., n_q=11 28 | Xi=[1/4, 0.0714285714285714, 0.785714285714286, 0.0714285714285714, 0.0714285714285714, 0.399403576166799, 0.100596423833201, 0.100596423833201, 0.399403576166799, 0.399403576166799, 0.100596423833201 29 | 1/4, 0.0714285714285714, 0.0714285714285714, 0.785714285714286, 0.0714285714285714, 0.100596423833201, 0.399403576166799, 0.100596423833201, 0.399403576166799, 0.100596423833201, 0.399403576166799 30 | 1/4, 0.0714285714285714, 0.0714285714285714, 0.0714285714285714, 0.785714285714286, 0.100596423833201, 0.100596423833201, 0.399403576166799, 0.100596423833201, 0.399403576166799, 0.399403576166799]; 31 | WF=[-0.013155555555555, 0.007622222222222*ones(1,4), 0.024888888888888*ones(1,6)]; 32 | 33 | case 'Q1' 34 | % - the reference cube with coordinates: 35 | % [-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1], 36 | % [-1,-1,1], [1,-1,1], [1,1,1], [-1,1,1] 37 | % - (2x2x2)-point quadrature rule, i.e., n_q=8 38 | pt = 1/sqrt(3); 39 | Xi=[-pt,-pt,-pt,-pt, pt, pt, pt, pt 40 | -pt,-pt, pt, pt,-pt,-pt, pt, pt 41 | -pt, pt,-pt, pt,-pt, pt,-pt, pt]; 42 | WF=[1,1,1,1,1,1,1,1]; 43 | 44 | case 'Q2' 45 | % - the reference cube with coordinates: 46 | % [-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1], 47 | % [-1,-1,1], [1,-1,1], [1,1,1], [-1,1,1] 48 | % - (3x3x3)-point quadrature rule, i.e., n_q=27 49 | pt = sqrt(3/5); 50 | Xi=[-pt,-pt,-pt,-pt,-pt,-pt,-pt,-pt,-pt, 0, 0, 0, 0, 0, 0, 0, 0, 0, pt, pt, pt, pt, pt, pt, pt, pt, pt 51 | -pt,-pt,-pt, 0, 0, 0, pt, pt, pt,-pt,-pt,-pt, 0, 0, 0, pt, pt, pt,-pt,-pt,-pt, 0, 0, 0, pt, pt, pt 52 | -pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt]; 53 | WF= ((5/9)^3)* [1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1] +... 54 | ((5/9)^2)*(8/9)* [0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0] +... 55 | ((8/9)^2)*(5/9)* [0 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0] +... 56 | ((8/9)^3)* [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0]; 57 | 58 | otherwise; disp('Bad choice of element type'); 59 | end 60 | -------------------------------------------------------------------------------- /elasticity/elasticity_3D/vector_volume.m: -------------------------------------------------------------------------------- 1 | % 2 | function f_V=vector_volume(ELEM,COORD,f_V_int,HatP,WEIGHT) 3 | 4 | % ====================================================================== 5 | % 6 | % Assembling of the vector of volume forces 7 | % 8 | % output: 9 | % f_V - vector of volume forces, size(f_V)=(3,n_n) where n_n is 10 | % the number of nodes 11 | % input data: 12 | % ELEM - to indicate nodes belonging to each element 13 | % size(ELEM)=(n_p,n_e) where n_e is a number of elements 14 | % and n_p is a number of the nodes within one element 15 | % COORD - coordinates of the nodes, size(COORD)=(3,n_n) 16 | % f_V_int - values of volume forces at integration points 17 | % size(f_V_int)=(3,n_int), where n_int=n_e*n_q is a number 18 | % of integration points, n_q is a number of quadrature pnts. 19 | % HatP - values of the basis functions at quadrature points, 20 | % size(HatP)=(n_p,n_q) 21 | % WEIGHT - weight coefficients, size(WEIGHT)=(1,n_int) 22 | % 23 | % ========================================================================= 24 | 25 | % 26 | % Auxilliary notation 27 | % 28 | n_n=size(COORD,2); % number of nodes including midpoints 29 | n_e=size(ELEM,2); % number of elements 30 | n_p=size(ELEM,1); % number of vertices per element 31 | n_q=size(HatP,2); % number of quadratic points 32 | n_int = n_e*n_q ; % total number of integrations points 33 | 34 | % extension of the input array HatP by replication 35 | % size(HatPhi)=(n_p,n_int) 36 | HatPhi=repmat(HatP,1,n_e); 37 | 38 | % 39 | % Assembling of the vector of volume forces, size(f_V)=(3,n_n) 40 | % 41 | % values at integration points, size(vF1)=size(vF2)=size(vF2)=(n_p,n_int) 42 | vF1 = HatPhi.*(ones(n_p,1)*(WEIGHT.*f_V_int(1,:))); 43 | vF2 = HatPhi.*(ones(n_p,1)*(WEIGHT.*f_V_int(2,:))); 44 | vF3 = HatPhi.*(ones(n_p,1)*(WEIGHT.*f_V_int(3,:))); 45 | % row and column indices, size(iF)=size(jF)=(n_p,n_int) 46 | iF = ones(n_p,n_int); 47 | jF = kron(ELEM,ones(1,n_q)); 48 | % the asssembling by using the sparse command - values v for duplicate 49 | % doubles i,j are automatically added together 50 | f_V = [ sparse(iF(:), jF(:), vF1(:), 1, n_n); 51 | sparse(iF(:), jF(:), vF2(:), 1, n_n); 52 | sparse(iF(:), jF(:), vF3(:), 1, n_n) ]; 53 | 54 | -------------------------------------------------------------------------------- /plasticity/plasticity_DP_2D/draw_mesh.m: -------------------------------------------------------------------------------- 1 | function draw_mesh(coord,elem,elem_type) 2 | 3 | % ========================================================================= 4 | % 5 | % This function draws mesh and nodal point on the surface of the body 6 | % 7 | % input data: 8 | % coord - coordinates of the nodes, size(coord)=(2,n_n) where n_n is a 9 | % number of nodes 10 | % elem - array containing numbers of nodes defining each element, 11 | % size(elem)=(n_p,n_e), n_e = number of elements 12 | % elem_type - the type of finite elements; available choices: 13 | % 'P1', 'P2', 'Q1', 'Q2' 14 | % 15 | % ====================================================================== 16 | % 17 | 18 | figure 19 | hold on 20 | coord_aux = [coord;zeros(1,size(coord,2))]; 21 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 22 | patch('Faces',elem(1:3,:)','Vertices',coord_aux','FaceVertexCData',... 23 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 24 | else 25 | patch('Faces',elem(1:4,:)','Vertices',coord_aux','FaceVertexCData',... 26 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 27 | end 28 | 29 | plot( coord(1,:),coord(2,:), 'b.', 'MarkerSize',10); 30 | axis equal; % real ratios 31 | view(2); % standard view in 2D 32 | hold off; 33 | axis off; 34 | end -------------------------------------------------------------------------------- /plasticity/plasticity_DP_2D/draw_quantity.m: -------------------------------------------------------------------------------- 1 | function draw_quantity(coord,elem,U,Q_node,elem_type,size_xy) 2 | 3 | % ========================================================================= 4 | % 5 | % This function depicts prescribed nodal quantity 6 | % 7 | % input data: 8 | % coord - coordinates of the nodes, size(coord)=(2,n_n) where n_n is a 9 | % number of nodes 10 | % elem - array containing numbers of nodes defining each element, 11 | % size(elem)=(n_p,n_e), n_e = number of elements 12 | % U - nodal displacements, size(U)=(2,n_n) to catch deformed shape 13 | % if the deformed shape is not required then set 0*U 14 | % Q_node - prescribed nodal quantity, size(Q_node)=(1,n_n) 15 | % elem_type - the type of finite elements; available choices: 16 | % 'P1', 'P2', 'Q1', 'Q2' 17 | % size_xy - size of the body in x and y direction (integer) 18 | % body=(0,size_xy)x(0,size_xy) 19 | % 20 | % ====================================================================== 21 | % 22 | 23 | figure; 24 | hold on; 25 | 26 | % visualization of the quantity 27 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 28 | s = patch('Faces',elem(1:3,:)','Vertices',coord'+U',... 29 | 'FaceVertexCData',Q_node','FaceColor','interp','EdgeColor','none'); 30 | else 31 | s = patch('Faces',elem(1:4,:)','Vertices',coord'+U',... 32 | 'FaceVertexCData',Q_node','FaceColor','interp','EdgeColor','none'); 33 | end 34 | if ~isOctave 35 | alpha(s,.5); 36 | end 37 | colorbar; 38 | 39 | % undeformed shape of the body 40 | plot([0,size_xy],[0,0]) 41 | plot([0,size_xy],[size_xy,size_xy]) 42 | plot([0,0],[0,size_xy]) 43 | plot([size_xy,size_xy],[0,size_xy]) 44 | 45 | % 46 | box on 47 | view(2); % standard view in 2D 48 | axis equal; % real ratios 49 | hold off; 50 | axis off; 51 | end -------------------------------------------------------------------------------- /plasticity/plasticity_DP_2D/enlarge_axis.m: -------------------------------------------------------------------------------- 1 | function enlarge_axis(alpha1,alpha2) 2 | ax=axis; 3 | if strcmp(get(gca,'XScale'),'log') 4 | ax(1)=log10(ax(1)); 5 | ax(2)=log10(ax(2)); 6 | end 7 | if strcmp(get(gca,'YScale'),'log') 8 | ax(3)=log10(ax(3)); 9 | ax(4)=log10(ax(4)); 10 | end 11 | 12 | ax_new=ax*[[1+alpha2 -alpha2; -alpha2 1+alpha2], zeros(2); zeros(2), [1+alpha1 -alpha1; -alpha1 1+alpha1]]; 13 | 14 | if strcmp(get(gca,'XScale'),'log') 15 | ax_new(1)=10^ax_new(1); 16 | ax_new(2)=10^ax_new(2); 17 | end 18 | if strcmp(get(gca,'YScale'),'log') 19 | ax_new(3)=10^ax_new(3); 20 | ax_new(4)=10^ax_new(4); 21 | end 22 | 23 | axis(ax_new); 24 | end 25 | 26 | -------------------------------------------------------------------------------- /plasticity/plasticity_DP_2D/isOctave.m: -------------------------------------------------------------------------------- 1 | function retval = isOctave() 2 | persistent cacheval; % speeds up repeated calls 3 | 4 | if isempty (cacheval) 5 | cacheval = (exist ('OCTAVE_VERSION', 'builtin') > 0); 6 | end 7 | 8 | retval = cacheval; 9 | end -------------------------------------------------------------------------------- /plasticity/plasticity_DP_2D/quadrature_volume.m: -------------------------------------------------------------------------------- 1 | function [Xi, WF] = quadrature_volume(elem_type) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function specifies a numerical quadrature for volume integration, 5 | % depending on a chosen finite element. The quadratures suggested 6 | % below can be simply replaced by another ones. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % 11 | % output data: 12 | % Xi - local coordinates of quadrature points, size(Xi)=(2,n_q) 13 | % WF - weight factors, size(WF)=(1,n_q) 14 | %-------------------------------------------------------------------------- 15 | 16 | switch(elem_type) 17 | 18 | case 'P1' 19 | % - the reference triangle with coordinates: 20 | % [0,0], [1,0], [0,1] 21 | % - 1-point quadrature rule, i.e., n_q=1 22 | Xi=[1/3; 1/3]; WF=1/2; 23 | 24 | case 'P2' 25 | % - the reference triangle with coordinates: 26 | % [0,0], [1,0], [0,1] 27 | % - 7-point quadrature rule, i.e., n_q=7 28 | Xi=[0.1012865073235, 0.7974269853531, 0.1012865073235, ... 29 | 0.4701420641051, 0.4701420641051, 0.0597158717898, 1/3; 30 | 0.1012865073235, 0.1012865073235, 0.7974269853531, ... 31 | 0.0597158717898, 0.4701420641051, 0.4701420641051, 1/3]; 32 | WF=[0.1259391805448, 0.1259391805448, 0.1259391805448, ... 33 | 0.1323941527885, 0.1323941527885, 0.1323941527885, 0.225]/2; 34 | 35 | case 'Q1' 36 | % - the reference square with coordinates: 37 | % [-1,-1], [1,-1], [1,1], [-1,1] 38 | % - (2x2)-point quadrature rule, i.e., n_q=4 39 | pt = 1/sqrt(3); 40 | Xi=[-pt,-pt, pt, pt 41 | -pt, pt,-pt, pt]; 42 | WF=[1,1,1,1]; 43 | 44 | case 'Q2' 45 | % - the reference square with coordinates: 46 | % [-1,-1], [1,-1], [1,1], [-1,1] 47 | % - (3x3)-point quadrature rule, i.e., n_q=9 48 | pt = sqrt(3/5); 49 | Xi=[-pt, pt, pt, -pt, 0, pt, 0, -pt, 0 50 | -pt, -pt, pt, pt, -pt, 0, pt, 0, 0]; 51 | WF=[25/81 25/81 25/81 25/81 40/81 40/81 40/81 40/81 64/81]; 52 | 53 | otherwise; disp('Bad choice of element type'); 54 | end 55 | -------------------------------------------------------------------------------- /plasticity/plasticity_DP_2D/test_load_paths.m: -------------------------------------------------------------------------------- 1 | level=3; 2 | 3 | linewdth=2; 4 | 5 | elem_type='P1'; 6 | plasticity_DP_fem; 7 | zeta_hist_P1=zeta_hist(1:step); pressure_hist_P1=pressure_hist(1:step); 8 | 9 | elem_type='P2'; 10 | plasticity_DP_fem; 11 | zeta_hist_P2=zeta_hist(1:step); pressure_hist_P2=pressure_hist(1:step); 12 | 13 | elem_type='Q1'; 14 | plasticity_DP_fem; 15 | zeta_hist_Q1=zeta_hist(1:step); pressure_hist_Q1=pressure_hist(1:step); 16 | 17 | elem_type='Q2'; 18 | plasticity_DP_fem; 19 | zeta_hist_Q2=zeta_hist(1:step); pressure_hist_Q2=pressure_hist(1:step); 20 | 21 | figure 22 | semilogx(zeta_hist_P1,pressure_hist_P1/c0,'-',... 23 | zeta_hist_P2,pressure_hist_P2/c0,'-',... 24 | zeta_hist_Q1,pressure_hist_Q1/c0,'-',... 25 | zeta_hist_Q2,pressure_hist_Q2/c0,'-','LineWidth',linewdth); 26 | xlabel('displacement'); ylabel('normalized pressure'); 27 | legend('P1 elements','P2 elements','Q1 elements','Q2 elements','location','southeast') 28 | axis tight; enlarge_axis(0.05,0.05); 29 | 30 | if printout 31 | fig = gcf; fig.PaperPositionMode = 'auto'; fig_pos = fig.PaperPosition; fig.PaperSize = [fig_pos(3) fig_pos(4)]; 32 | print('-painters','-dpdf',strcat('figures/fig_DP_2D_load_path_level_',num2str(level))) 33 | end 34 | 35 | -------------------------------------------------------------------------------- /plasticity/plasticity_DP_2D/transformation.m: -------------------------------------------------------------------------------- 1 | % 2 | function Q_node=transformation(Q_int,elem,weight) 3 | 4 | % ====================================================================== 5 | % 6 | % Transformation of function values at integration points to function 7 | % values at nodes of the finite element mesh. 8 | % 9 | % output: 10 | % Q_node - values of a function Q at nodes of the FE mesh, 11 | % size(Q_node)=(1,n_n), where n_n is the number of nodes 12 | % 13 | % input data: 14 | % Q_int - values of a function Q at integration points, size(Q_int)=(1,n_int) 15 | % elem - to indicate nodes belonging to each element 16 | % size(elem)=(n_p,n_e) where n_e is a number of elements 17 | % and n_p is a number of the nodes within one element 18 | % weight - weight factors at integration points, size(weight)=(1,n_int) 19 | % 20 | % ========================================================================= 21 | 22 | % 23 | % Auxilliary notation 24 | % 25 | n_e=size(elem,2); % number of elements 26 | n_p=size(elem,1); % number of vertices per element 27 | n_int=length(weight); % total number of integrations points 28 | n_q=n_int/n_e; % number of quadrature points on one element 29 | 30 | % 31 | % F1 - 1*n_n array, to each node we compute numerically the integral of Q 32 | % through a vicinity of the node 33 | % F2 - 1*n_n array, to each node we compute the area of the vicinity 34 | % 35 | 36 | % values at integration points, size(vF1)=size(vF2)=(n_p,n_int) 37 | vF1 = ones(n_p,1)*(weight.*Q_int); 38 | vF2 = ones(n_p,1)*weight; 39 | 40 | % row and column indices, size(iF)=size(jF)=(n_p,n_int) 41 | iF = ones(n_p,n_int); 42 | jF = kron(elem,ones(1,n_q)); 43 | 44 | % the asssembling by using the sparse command - values v for duplicate 45 | % doubles i,j are automatically added together 46 | F1 = sparse(iF(:), jF(:), vF1(:)) ; 47 | F2 = sparse(iF(:), jF(:), vF2(:)) ; 48 | 49 | % 50 | % Approximated values of the function Q at nodes of the FE mesh 51 | % 52 | Q_node = F1./F2; 53 | 54 | -------------------------------------------------------------------------------- /plasticity/plasticity_DP_3D/draw_mesh.m: -------------------------------------------------------------------------------- 1 | function draw_mesh(coord,surf,elem_type) 2 | 3 | % ========================================================================= 4 | % 5 | % This function draws mesh and nodal point on the surface of the body 6 | % 7 | % input data: 8 | % coord - coordinates of the nodes, size(coord)=(3,n_n) where n_n is a 9 | % number of nodes 10 | % surf - array containing numbers of nodes defining each surface element, 11 | % size(surf)=(n_p,n_s), n_s = number of surface elements 12 | % elem_type - the type of finite elements; available choices: 13 | % 'P1', 'P2', 'Q1', 'Q2' 14 | % 15 | % ====================================================================== 16 | % 17 | 18 | figure 19 | hold on 20 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 21 | patch('Faces',surf(1:3,:)','Vertices',coord','FaceVertexCData',... 22 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 23 | else 24 | patch('Faces',surf(1:4,:)','Vertices',coord','FaceVertexCData',... 25 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 26 | end 27 | ind=unique(surf(:)); 28 | plot3( coord(1,ind),coord(2,ind),coord(3,ind), 'b.', 'MarkerSize',10); 29 | axis equal; % real ratios 30 | view(3); % standard view ve 3D 31 | hold off; 32 | axis off; 33 | end -------------------------------------------------------------------------------- /plasticity/plasticity_DP_3D/draw_quantity.m: -------------------------------------------------------------------------------- 1 | function draw_quantity(coord,surf,U,Q_node,elem_type,size_xy,size_z) 2 | 3 | % ========================================================================= 4 | % 5 | % This function depicts prescribed nodal quantity 6 | % 7 | % input data: 8 | % coord - coordinates of the nodes, size(coord)=(3,n_n) where n_n is a 9 | % number of nodes 10 | % surf - array containing numbers of nodes defining each surface 11 | % element, size(surf)=(n_p,n_s), n_s = number of surface elements 12 | % U - nodal displacements, size(U)=(3,n_n) to catch deformed shape 13 | % if the deformed shape is not required then set 0*U 14 | % Q_node - prescribed nodal quantity, size(Q_node)=(1,n_n) 15 | % elem_type - the type of finite elements; available choices: 16 | % 'P1', 'P2', 'Q1', 'Q2' 17 | % size_xy - size of the body in x and y direction (integer) 18 | % size_z - size of the body in z-direction (integer) 19 | % body=(0,size_xy)x(0,size_xy)x(0,size_z) 20 | % 21 | % ====================================================================== 22 | % 23 | 24 | figure; 25 | hold on; 26 | 27 | % visualization of the quantity 28 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 29 | s = patch('Faces',surf(1:3,:)','Vertices',coord'+U',... 30 | 'FaceVertexCData',Q_node','FaceColor','interp','EdgeColor','none'); 31 | else 32 | s = patch('Faces',surf(1:4,:)','Vertices',coord'+U',... 33 | 'FaceVertexCData',Q_node','FaceColor','interp','EdgeColor','none'); 34 | end 35 | if ~isOctave 36 | alpha(s,.5); 37 | end 38 | colorbar; 39 | 40 | % undeformed shape of the body 41 | plot3([0,size_xy],[0,0],[0,0]) 42 | plot3([0,size_xy],[0,0],[size_z,size_z]) 43 | plot3([0,size_xy],[size_xy,size_xy],[0,0]) 44 | plot3([0,size_xy],[size_xy,size_xy],[size_z,size_z]) 45 | plot3([0,0],[0,size_xy],[0,0]) 46 | plot3([0,0],[0,size_xy],[size_z,size_z]) 47 | plot3([size_xy,size_xy],[0,size_xy],[0,0]) 48 | plot3([size_xy,size_xy],[0,size_xy],[size_z,size_z]) 49 | plot3([0,0],[0,0],[0,size_z]) 50 | plot3([0,0],[size_xy,size_xy],[0,size_z]) 51 | plot3([size_xy,size_xy],[0,0],[0,size_z]) 52 | plot3([size_xy,size_xy],[size_xy,size_xy],[0,size_z]) 53 | 54 | % 55 | box on 56 | view(3); % standard view in 3D 57 | axis equal; % real ratios 58 | hold off; 59 | axis off; 60 | end -------------------------------------------------------------------------------- /plasticity/plasticity_DP_3D/isOctave.m: -------------------------------------------------------------------------------- 1 | function retval = isOctave() 2 | persistent cacheval; % speeds up repeated calls 3 | 4 | if isempty (cacheval) 5 | cacheval = (exist ('OCTAVE_VERSION', 'builtin') > 0); 6 | end 7 | 8 | retval = cacheval; 9 | end -------------------------------------------------------------------------------- /plasticity/plasticity_DP_3D/quadrature_volume.m: -------------------------------------------------------------------------------- 1 | function [Xi, WF] = quadrature_volume(elem_type) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function specifies a numerical quadrature for volume integration, 5 | % depending on a chosen finite element. The quadratures suggested 6 | % below can be simply replaced by another ones. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % 11 | % output data: 12 | % Xi - local coordinates of quadrature points, size(Xi)=(3,n_q) 13 | % WF - weight factors, size(WF)=(1,n_q) 14 | %-------------------------------------------------------------------------- 15 | 16 | switch(elem_type) 17 | 18 | case 'P1' 19 | % - the reference tetrahedron with coordinates: 20 | % [0,0,0], [1,0,0], [0,1,0], [0,0,1] 21 | % - 1-point quadrature rule, i.e., n_q=1 22 | Xi=[1/4; 1/4; 1/4]; WF=1/6; 23 | 24 | case 'P2' 25 | % - the reference tetrahedron with coordinates: 26 | % [0,0,0], [1,0,0], [0,1,0], [0,0,1] 27 | % - 11-point quadrature rule, i.e., n_q=11 28 | Xi=[1/4, 0.0714285714285714, 0.785714285714286, 0.0714285714285714, 0.0714285714285714, 0.399403576166799, 0.100596423833201, 0.100596423833201, 0.399403576166799, 0.399403576166799, 0.100596423833201 29 | 1/4, 0.0714285714285714, 0.0714285714285714, 0.785714285714286, 0.0714285714285714, 0.100596423833201, 0.399403576166799, 0.100596423833201, 0.399403576166799, 0.100596423833201, 0.399403576166799 30 | 1/4, 0.0714285714285714, 0.0714285714285714, 0.0714285714285714, 0.785714285714286, 0.100596423833201, 0.100596423833201, 0.399403576166799, 0.100596423833201, 0.399403576166799, 0.399403576166799]; 31 | WF=[-0.013155555555555, 0.007622222222222*ones(1,4), 0.024888888888888*ones(1,6)]; 32 | 33 | case 'Q1' 34 | % - the reference cube with coordinates: 35 | % [-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1], 36 | % [-1,-1,1], [1,-1,1], [1,1,1], [-1,1,1] 37 | % - (2x2x2)-point quadrature rule, i.e., n_q=8 38 | pt = 1/sqrt(3); 39 | Xi=[-pt,-pt,-pt,-pt, pt, pt, pt, pt 40 | -pt,-pt, pt, pt,-pt,-pt, pt, pt 41 | -pt, pt,-pt, pt,-pt, pt,-pt, pt]; 42 | WF=[1,1,1,1,1,1,1,1]; 43 | 44 | case 'Q2' 45 | % - the reference cube with coordinates: 46 | % [-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1], 47 | % [-1,-1,1], [1,-1,1], [1,1,1], [-1,1,1] 48 | % - (3x3x3)-point quadrature rule, i.e., n_q=27 49 | pt = sqrt(3/5); 50 | Xi=[-pt,-pt,-pt,-pt,-pt,-pt,-pt,-pt,-pt, 0, 0, 0, 0, 0, 0, 0, 0, 0, pt, pt, pt, pt, pt, pt, pt, pt, pt 51 | -pt,-pt,-pt, 0, 0, 0, pt, pt, pt,-pt,-pt,-pt, 0, 0, 0, pt, pt, pt,-pt,-pt,-pt, 0, 0, 0, pt, pt, pt 52 | -pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt]; 53 | WF= ((5/9)^3)* [1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1] +... 54 | ((5/9)^2)*(8/9)* [0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0] +... 55 | ((8/9)^2)*(5/9)* [0 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0] +... 56 | ((8/9)^3)* [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0]; 57 | 58 | otherwise; disp('Bad choice of element type'); 59 | end 60 | -------------------------------------------------------------------------------- /plasticity/plasticity_DP_3D/transformation.m: -------------------------------------------------------------------------------- 1 | % 2 | function Q_node=transformation(Q_int,elem,weight) 3 | 4 | % ====================================================================== 5 | % 6 | % Transformation of function values at integration points to function 7 | % values at nodes of the finite element mesh. 8 | % 9 | % output: 10 | % Q_node - values of a function Q at nodes of the FE mesh, 11 | % size(Q_node)=(1,n_n), where n_n is the number of nodes 12 | % 13 | % input data: 14 | % Q_int - values of a function Q at integration points, size(Q_int)=(1,n_int) 15 | % elem - to indicate nodes belonging to each element 16 | % size(elem)=(n_p,n_e) where n_e is a number of elements 17 | % and n_p is a number of the nodes within one element 18 | % weight - weight factors at integration points, size(weight)=(1,n_int) 19 | % 20 | % ========================================================================= 21 | 22 | % 23 | % Auxilliary notation 24 | % 25 | n_e=size(elem,2); % number of elements 26 | n_p=size(elem,1); % number of vertices per element 27 | n_int=length(weight); % total number of integrations points 28 | n_q=n_int/n_e; % number of quadrature points on one element 29 | 30 | % 31 | % F1 - 1*n_n array, to each node we compute numerically the integral of Q 32 | % through a vicinity of the node 33 | % F2 - 1*n_n array, to each node we compute the area of the vicinity 34 | % 35 | 36 | % values at integration points, size(vF1)=size(vF2)=(n_p,n_int) 37 | vF1 = ones(n_p,1)*(weight.*Q_int); 38 | vF2 = ones(n_p,1)*weight; 39 | 40 | % row and column indices, size(iF)=size(jF)=(n_p,n_int) 41 | iF = ones(n_p,n_int); 42 | jF = kron(elem,ones(1,n_q)); 43 | 44 | % the asssembling by using the sparse command - values v for duplicate 45 | % doubles i,j are automatically added together 46 | F1 = sparse(iF(:), jF(:), vF1(:)) ; 47 | F2 = sparse(iF(:), jF(:), vF2(:)) ; 48 | 49 | % 50 | % Approximated values of the function Q at nodes of the FE mesh 51 | % 52 | Q_node = F1./F2; 53 | 54 | -------------------------------------------------------------------------------- /plasticity/plasticity_VM_2D/draw_mesh.m: -------------------------------------------------------------------------------- 1 | function draw_mesh(coord,elem,elem_type) 2 | 3 | % ========================================================================= 4 | % 5 | % This function draws mesh and nodal point on the surface of the body 6 | % 7 | % input data: 8 | % coord - coordinates of the nodes, size(coord)=(2,n_n) where n_n is a 9 | % number of nodes 10 | % elem - array containing numbers of nodes defining each element, 11 | % size(elem)=(n_p,n_e), n_e = number of elements 12 | % elem_type - the type of finite elements; available choices: 13 | % 'P1', 'P2', 'Q1', 'Q2' 14 | % 15 | % ====================================================================== 16 | % 17 | 18 | figure 19 | hold on 20 | coord_aux = [coord;zeros(1,size(coord,2))]; 21 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 22 | patch('Faces',elem(1:3,:)','Vertices',coord_aux','FaceVertexCData',... 23 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 24 | else 25 | patch('Faces',elem(1:4,:)','Vertices',coord_aux','FaceVertexCData',... 26 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 27 | end 28 | 29 | plot( coord(1,:),coord(2,:), 'b.', 'MarkerSize',10); 30 | axis equal; % real ratios 31 | view(2); % standard view in 2D 32 | hold off; 33 | axis off; 34 | end -------------------------------------------------------------------------------- /plasticity/plasticity_VM_2D/draw_quantity.m: -------------------------------------------------------------------------------- 1 | function draw_quantity(coord,elem,U,Q_node,elem_type,... 2 | size_xy,size_hole) 3 | 4 | % ========================================================================= 5 | % 6 | % This function depicts prescribed nodal quantity 7 | % 8 | % input data: 9 | % coord - coordinates of the nodes, size(coord)=(2,n_n) where n_n is a 10 | % number of nodes 11 | % elem - array containing numbers of nodes defining each element, 12 | % size(elem)=(n_p,n_e), n_e = number of elements 13 | % U - nodal displacements, size(U)=(2,n_n) to catch deformed shape 14 | % if the deformed shape is not required then set 0*U 15 | % Q_node - prescribed nodal quantity, size(Q_node)=(1,n_n) 16 | % elem_type - the type of finite elements; available choices: 17 | % 'P1', 'P2', 'Q1', 'Q2' 18 | % size_xy - size of the body in x and y direction (integer) 19 | % size_hole - size of the hole in the body (integer) 20 | % size_hole < size_xy 21 | % body=(0,size_xy) x(0,size_xy) \setminus 22 | % (0,size_hole)x(0,size_hole) 23 | % 24 | % ====================================================================== 25 | % 26 | 27 | figure; 28 | hold on; 29 | 30 | % visualization of the quantity 31 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 32 | s = patch('Faces',elem(1:3,:)','Vertices',coord'+U',... 33 | 'FaceVertexCData',Q_node','FaceColor','interp','EdgeColor','none'); 34 | else 35 | s = patch('Faces',elem(1:4,:)','Vertices',coord'+U',... 36 | 'FaceVertexCData',Q_node','FaceColor','interp','EdgeColor','none'); 37 | end 38 | if ~isOctave 39 | alpha(s,.5); 40 | end 41 | colorbar; 42 | 43 | % undeformed shape of the body 44 | plot([size_hole,size_xy],[0,0]) 45 | plot([0,size_xy],[size_xy,size_xy]) 46 | plot([0,size_hole],[size_hole,size_hole]) 47 | plot([0,0],[size_hole,size_xy]) 48 | plot([size_hole,size_hole],[0,size_hole]) 49 | plot([size_xy,size_xy],[0,size_xy]) 50 | 51 | 52 | % 53 | box on 54 | view(2); % standard view ve 2D 55 | axis equal; % real ratios 56 | hold off; 57 | axis off; 58 | end -------------------------------------------------------------------------------- /plasticity/plasticity_VM_2D/isOctave.m: -------------------------------------------------------------------------------- 1 | function retval = isOctave() 2 | persistent cacheval; % speeds up repeated calls 3 | 4 | if isempty (cacheval) 5 | cacheval = (exist ('OCTAVE_VERSION', 'builtin') > 0); 6 | end 7 | 8 | retval = cacheval; 9 | end -------------------------------------------------------------------------------- /plasticity/plasticity_VM_2D/local_basis_surface.m: -------------------------------------------------------------------------------- 1 | function [HatP_s,DHatP1_s] = local_basis_surface(elem_type, Xi_s) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function evaluates local basis functions on a surface and their 5 | % derivatives at prescribed quadrature points depending on a chosen 6 | % finite elements. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % Xi_s - coordinates of the quadrature points, size(Xi_s)=(1,n_q_s) 11 | % 12 | % output data: 13 | % HatP_s - values of basis functions at the quadrature points, 14 | % size(HatP_s)=(n_p_s,n_q_s) 15 | % DHatP1_s - derivatives of basis functions at the quadrature points 16 | % in the direction xi_1, size(DHatP1_s)=(n_p_s,n_q_s) 17 | % n_p_s - number of basis functions on the surface 18 | % n_q_s - number of integration points within the surface 19 | %-------------------------------------------------------------------------- 20 | 21 | xi = Xi_s(1,:); 22 | 23 | switch(elem_type) 24 | case {'P1','Q1'} 25 | % - the reference line with coordinates: 26 | % -1, 1 27 | % - n_p_s=2, n_q_s=length(xi_1) 28 | HatP_s = (1/2)*[1-xi; 1+xi] ; 29 | DHatP1_s = [-1/2; 1/2]; 30 | 31 | case {'P2','Q2'} 32 | % - the reference line with coordinates: 33 | % -1, 1 34 | % - coordinates of midpoint: 35 | % 0 36 | % - n_p_s=3, n_q_s=length(xi_1) 37 | HatP_s = [xi.*(xi-1)/2; xi.*(xi+1)/2; (xi+1).*(1-xi)] ; 38 | DHatP1_s = [ xi-1/2; xi+1/2; -2*xi]; 39 | 40 | otherwise; disp('Bad choise of element type'); 41 | end 42 | -------------------------------------------------------------------------------- /plasticity/plasticity_VM_2D/quadrature_surface.m: -------------------------------------------------------------------------------- 1 | function [Xi_s, WF_s] = quadrature_surface(elem_type) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function specifies a numerical quadrature for surface integration, 5 | % depending on a chosen finite element. The quadratures suggested 6 | % below can be simply replaced by another ones. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % 11 | % output data: 12 | % Xi_s - local coordinates of quadrature points, size(Xi_s)=(1,n_q_s) 13 | % WF_s - weight factors, size(WF_s)=(1,n_q_s) 14 | %-------------------------------------------------------------------------- 15 | 16 | switch(elem_type) 17 | 18 | case {'P1','Q1'} 19 | % - surface is created by the reference line with coordinates: 20 | % -1, 1 21 | % - 1-point quadrature rule, i.e., n_q_s=1 22 | Xi_s=0; WF_s=2; 23 | 24 | case {'P2','Q2'} 25 | % - surface is created by the reference line with coordinates: 26 | % -1, 1 27 | % - 2-point quadrature rule, i.e., n_q_s=2 28 | pt = 1/sqrt(3); 29 | Xi_s=[-pt,pt]; 30 | WF_s=[1,1]; 31 | 32 | otherwise; disp('Bad choise of element type'); 33 | end 34 | -------------------------------------------------------------------------------- /plasticity/plasticity_VM_2D/quadrature_volume.m: -------------------------------------------------------------------------------- 1 | function [Xi, WF] = quadrature_volume(elem_type) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function specifies a numerical quadrature for volume integration, 5 | % depending on a chosen finite element. The quadratures suggested 6 | % below can be simply replaced by another ones. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % 11 | % output data: 12 | % Xi - local coordinates of quadrature points, size(Xi)=(2,n_q) 13 | % WF - weight factors, size(WF)=(1,n_q) 14 | %-------------------------------------------------------------------------- 15 | 16 | switch(elem_type) 17 | 18 | case 'P1' 19 | % - the reference triangle with coordinates: 20 | % [0,0], [1,0], [0,1] 21 | % - 1-point quadrature rule, i.e., n_q=1 22 | Xi=[1/3; 1/3]; WF=1/2; 23 | 24 | case 'P2' 25 | % - the reference triangle with coordinates: 26 | % [0,0], [1,0], [0,1] 27 | % - 7-point quadrature rule, i.e., n_q=7 28 | Xi=[0.1012865073235, 0.7974269853531, 0.1012865073235, ... 29 | 0.4701420641051, 0.4701420641051, 0.0597158717898, 1/3; 30 | 0.1012865073235, 0.1012865073235, 0.7974269853531, ... 31 | 0.0597158717898, 0.4701420641051, 0.4701420641051, 1/3]; 32 | WF=[0.1259391805448, 0.1259391805448, 0.1259391805448, ... 33 | 0.1323941527885, 0.1323941527885, 0.1323941527885, 0.225]/2; 34 | 35 | case 'Q1' 36 | % - the reference square with coordinates: 37 | % [-1,-1], [1,-1], [1,1], [-1,1] 38 | % - (2x2)-point quadrature rule, i.e., n_q=4 39 | pt = 1/sqrt(3); 40 | Xi=[-pt,-pt, pt, pt 41 | -pt, pt,-pt, pt]; 42 | WF=[1,1,1,1]; 43 | 44 | case 'Q2' 45 | % - the reference square with coordinates: 46 | % [-1,-1], [1,-1], [1,1], [-1,1] 47 | % - (3x3)-point quadrature rule, i.e., n_q=9 48 | pt = sqrt(3/5); 49 | Xi=[-pt, pt, pt, -pt, 0, pt, 0, -pt, 0 50 | -pt, -pt, pt, pt, -pt, 0, pt, 0, 0]; 51 | WF=[25/81 25/81 25/81 25/81 40/81 40/81 40/81 40/81 64/81]; 52 | 53 | otherwise; disp('Bad choice of element type'); 54 | end 55 | -------------------------------------------------------------------------------- /plasticity/plasticity_VM_2D/transformation.m: -------------------------------------------------------------------------------- 1 | % 2 | function Q_node=transformation(Q_int,elem,weight) 3 | 4 | % ====================================================================== 5 | % 6 | % Transformation of function values at integration points to function 7 | % values at nodes of the finite element mesh. 8 | % 9 | % output: 10 | % Q_node - values of a function Q at nodes of the FE mesh, 11 | % size(Q_node)=(1,n_n), where n_n is the number of nodes 12 | % 13 | % input data: 14 | % Q_int - values of a function Q at integration points, size(Q_int)=(1,n_int) 15 | % elem - to indicate nodes belonging to each element 16 | % size(elem)=(n_p,n_e) where n_e is a number of elements 17 | % and n_p is a number of the nodes within one element 18 | % weight - weight factors at integration points, size(weight)=(1,n_int) 19 | % 20 | % ========================================================================= 21 | 22 | % 23 | % Auxilliary notation 24 | % 25 | n_e=size(elem,2); % number of elements 26 | n_p=size(elem,1); % number of vertices per element 27 | n_int=length(weight); % total number of integrations points 28 | n_q=n_int/n_e; % number of quadrature points on one element 29 | 30 | % 31 | % F1 - 1*n_n array, to each node we compute numerically the integral of Q 32 | % through a vicinity of the node 33 | % F2 - 1*n_n array, to each node we compute the area of the vicinity 34 | % 35 | 36 | % values at integration points, size(vF1)=size(vF2)=(n_p,n_int) 37 | vF1 = ones(n_p,1)*(weight.*Q_int); 38 | vF2 = ones(n_p,1)*weight; 39 | 40 | % row and column indices, size(iF)=size(jF)=(n_p,n_int) 41 | iF = ones(n_p,n_int); 42 | jF = kron(elem,ones(1,n_q)); 43 | 44 | % the asssembling by using the sparse command - values v for duplicate 45 | % doubles i,j are automatically added together 46 | F1 = sparse(iF(:), jF(:), vF1(:)) ; 47 | F2 = sparse(iF(:), jF(:), vF2(:)) ; 48 | 49 | % 50 | % Approximated values of the function Q at nodes of the FE mesh 51 | % 52 | Q_node = F1./F2; 53 | 54 | -------------------------------------------------------------------------------- /plasticity/plasticity_VM_2D/vector_traction.m: -------------------------------------------------------------------------------- 1 | function f_t = vector_traction(ELEM_s,COORD,f_t_int,HatP_s,DHatP1_s,WF_s) 2 | 3 | % ========================================================================= 4 | % 5 | % Assembling of the vector of traction forces acting on the upper side of 6 | % the 2D body 7 | % 8 | % output: 9 | % f_t - vector of traction forces, size(f_V)=(2,n_n), where n_n is 10 | % the number of nodes 11 | % 12 | % input data: 13 | % ELEM_s - to indicate nodes belonging to each surface element 14 | % size(ELEM_s)=(n_p_s,n_e_s) where n_e_s is a number of 15 | % surface elements n_p_s is a number of the nodes within one 16 | % surface element 17 | % COORD - coordinates of the nodes, size(COORD)=(2,n_n) 18 | % f_t_int - values of traction forces at integration points 19 | % size(f_t_int)=(2,n_int_s), where n_int_s=n_e_s*n_q_s is a 20 | % number of surface integration points and n_q_s is a number 21 | % of quadrature points on the surface 22 | % HatP_s - values of the surface basis functions at quadrature points 23 | % DHatP1_s - xi_1-derivatives of the surface basis functions at q. p. 24 | % size(HatP_s)=size(DHatP1_s)=(n_p_s,n_q_s) 25 | % WF_s - weight factors at surface quadrature points, 26 | % size(WF)=(1,n_q_s) 27 | % 28 | % ========================================================================= 29 | 30 | % 31 | % Auxilliary notation 32 | % 33 | 34 | n_n=size(COORD,2); % number of nodes including midpoints 35 | n_e_s=size(ELEM_s,2); % number of surface elements 36 | n_p_s=size(ELEM_s,1); % number of nodes within one surface element 37 | n_q_s=length(WF_s); % number of quadrature points on a surface element 38 | n_int_s=n_e_s*n_q_s ; % number of integration points on the surface 39 | % (on the upper side of the body) 40 | 41 | % 42 | % Jacobians and their determinants at surface integration points 43 | % 44 | 45 | % extension of the input arrays HatP_s,DHatP1_s by replication 46 | % size(HatPhi_s)=size(DHatPhi1_s)=(n_p_s,n_int_s) 47 | DHatPhi1_s=repmat(DHatP1_s,1,n_e_s); 48 | HatPhi_s=repmat(HatP_s,1,n_e_s) ; 49 | 50 | % coordinates of nodes defining each surface element 51 | % size(COORDs1)=(n_p_s,n_e_s) 52 | COORDs1=reshape(COORD(1,ELEM_s(:)),n_p_s,n_e_s); 53 | 54 | % coordinates of nodes around each surface integration point 55 | % size(COORDint1)=(n_p_s,n_int_s) 56 | COORDint1=kron(COORDs1,ones(1,n_q_s)); 57 | 58 | % components of the Jacobians: size=(1,n_int_s) 59 | J11=sum(COORDint1.*DHatPhi1_s); 60 | 61 | % determinant of the Jacobian: size=(1,n_int_s) 62 | DET_s=J11; 63 | 64 | % weight coefficients: size(WEIGHT)=(1,n_int_s) 65 | WEIGHT_s = abs(DET_s).*repmat(WF_s,1,n_e_s); 66 | 67 | % 68 | % Assembling of the vector of traction forces, size(f_V)=(2,n_n) 69 | % 70 | 71 | % auxilliary values at surface integration points, 72 | % size(vF1)=size(vF2)=(n_p_s,n_int_s) 73 | vF1 = HatPhi_s.*(ones(n_p_s,1)*(WEIGHT_s.*f_t_int(1,:))); 74 | vF2 = HatPhi_s.*(ones(n_p_s,1)*(WEIGHT_s.*f_t_int(2,:))); 75 | % row and column indices, size(iF)=size(jF)=(n_p_s,n_int_s) 76 | iF = ones(n_p_s,n_int_s); 77 | jF = kron(ELEM_s,ones(1,n_q_s)); 78 | % the asssembling by using the sparse command - values v for duplicate 79 | % doubles i,j are automatically added together 80 | f_t = [ sparse(iF(:), jF(:), vF1(:), 1, n_n); 81 | sparse(iF(:), jF(:), vF2(:), 1, n_n) ]; 82 | 83 | end -------------------------------------------------------------------------------- /plasticity/plasticity_VM_3D/draw_mesh.m: -------------------------------------------------------------------------------- 1 | function draw_mesh(coord,surf,elem_type) 2 | 3 | % ========================================================================= 4 | % 5 | % This function draws mesh and nodal point on the surface of the body 6 | % 7 | % input data: 8 | % coord - coordinates of the nodes, size(coord)=(3,n_n) where n_n is a 9 | % number of nodes 10 | % surf - array containing numbers of nodes defining each surface element, 11 | % size(surf)=(n_p,n_s), n_s = number of surface elements 12 | % elem_type - the type of finite elements; available choices: 13 | % 'P1', 'P2', 'Q1', 'Q2' 14 | % 15 | % ====================================================================== 16 | % 17 | 18 | figure 19 | hold on 20 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 21 | patch('Faces',surf(1:3,:)','Vertices',coord','FaceVertexCData',... 22 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 23 | else 24 | patch('Faces',surf(1:4,:)','Vertices',coord','FaceVertexCData',... 25 | 0*ones(size(coord,2),1),'FaceColor','white','EdgeColor','blue'); 26 | end 27 | ind=unique(surf(:)); 28 | plot3( coord(1,ind),coord(2,ind),coord(3,ind), 'b.', 'MarkerSize',10); 29 | axis equal; % real ratios 30 | view(3); % standard view ve 3D 31 | hold off; 32 | axis off; 33 | end -------------------------------------------------------------------------------- /plasticity/plasticity_VM_3D/draw_quantity.m: -------------------------------------------------------------------------------- 1 | function draw_quantity(coord,surf,U,Q_node,elem_type,... 2 | size_xy,size_z,size_hole) 3 | 4 | % ========================================================================= 5 | % 6 | % This function depicts prescribed nodal quantity 7 | % 8 | % input data: 9 | % coord - coordinates of the nodes, size(coord)=(3,n_n) where n_n is a 10 | % number of nodes 11 | % surf - array containing numbers of nodes defining each surface 12 | % element, size(surf)=(n_p,n_s), n_s = number of surface elements 13 | % U - nodal displacements, size(U)=(3,n_n) to catch deformed shape 14 | % if the deformed shape is not required then set 0*U 15 | % Q_node - prescribed nodal quantity, size(Q_node)=(1,n_n) 16 | % elem_type - the type of finite elements; available choices: 17 | % 'P1', 'P2', 'Q1', 'Q2' 18 | % size_xy - size of the body in x and y direction (integer) 19 | % size_z - size of the body in z-direction (integer) 20 | % size_hole - size of the hole in the body (integer) 21 | % size_hole < size_xy 22 | % body=(0,size_xy) x(0,size_xy) x(0,size_z)\setminus 23 | % (0,size_hole)x(0,size_hole)x(0,size_z) 24 | % 25 | % ====================================================================== 26 | % 27 | 28 | figure; 29 | hold on; 30 | 31 | % visualization of the quantity 32 | if strcmp(elem_type,'P1')||strcmp(elem_type,'P2') 33 | s = patch('Faces',surf(1:3,:)','Vertices',coord'+U',... 34 | 'FaceVertexCData',Q_node','FaceColor','interp','EdgeColor','none'); 35 | else 36 | s = patch('Faces',surf(1:4,:)','Vertices',coord'+U',... 37 | 'FaceVertexCData',Q_node','FaceColor','interp','EdgeColor','none'); 38 | end 39 | if ~isOctave 40 | alpha(s,.5); 41 | end 42 | colorbar; 43 | 44 | % undeformed shape of the body 45 | plot3([size_hole,size_xy],[0,0],[0,0]) 46 | plot3([size_hole,size_xy],[0,0],[size_z,size_z]) 47 | plot3([0,size_xy],[size_xy,size_xy],[0,0]) 48 | plot3([0,size_xy],[size_xy,size_xy],[size_z,size_z]) 49 | plot3([0,size_hole],[size_hole,size_hole],[0,0]) 50 | plot3([0,size_hole],[size_hole,size_hole],[size_z,size_z]) 51 | plot3([0,0],[size_hole,size_xy],[0,0]) 52 | plot3([0,0],[size_hole,size_xy],[size_z,size_z]) 53 | plot3([size_hole,size_hole],[0,size_hole],[0,0]) 54 | plot3([size_hole,size_hole],[0,size_hole],[size_z,size_z]) 55 | plot3([size_xy,size_xy],[0,size_xy],[0,0]) 56 | plot3([size_xy,size_xy],[0,size_xy],[size_z,size_z]) 57 | plot3([0,0],[size_hole,size_hole],[0,size_z]) 58 | plot3([0,0],[size_xy,size_xy],[0,size_z]) 59 | plot3([size_hole,size_hole],[0,0],[0,size_z]) 60 | plot3([size_hole,size_hole],[size_hole,size_hole],[0,size_z]) 61 | plot3([size_xy,size_xy],[0,0],[0,size_z]) 62 | plot3([size_xy,size_xy],[size_xy,size_xy],[0,size_z]) 63 | 64 | % 65 | box on 66 | view(3); % standard view in 3D 67 | axis equal; % real ratios 68 | hold off; 69 | axis off; 70 | end -------------------------------------------------------------------------------- /plasticity/plasticity_VM_3D/enlarge_axis.m: -------------------------------------------------------------------------------- 1 | function enlarge_axis(alpha1,alpha2) 2 | ax=axis; 3 | if strcmp(get(gca,'XScale'),'log') 4 | ax(1)=log10(ax(1)); 5 | ax(2)=log10(ax(2)); 6 | end 7 | if strcmp(get(gca,'YScale'),'log') 8 | ax(3)=log10(ax(3)); 9 | ax(4)=log10(ax(4)); 10 | end 11 | 12 | ax_new=ax*[[1+alpha2 -alpha2; -alpha2 1+alpha2], zeros(2); zeros(2), [1+alpha1 -alpha1; -alpha1 1+alpha1]]; 13 | 14 | if strcmp(get(gca,'XScale'),'log') 15 | ax_new(1)=10^ax_new(1); 16 | ax_new(2)=10^ax_new(2); 17 | end 18 | if strcmp(get(gca,'YScale'),'log') 19 | ax_new(3)=10^ax_new(3); 20 | ax_new(4)=10^ax_new(4); 21 | end 22 | 23 | axis(ax_new); 24 | end 25 | 26 | -------------------------------------------------------------------------------- /plasticity/plasticity_VM_3D/isOctave.m: -------------------------------------------------------------------------------- 1 | function retval = isOctave() 2 | persistent cacheval; % speeds up repeated calls 3 | 4 | if isempty (cacheval) 5 | cacheval = (exist ('OCTAVE_VERSION', 'builtin') > 0); 6 | end 7 | 8 | retval = cacheval; 9 | end -------------------------------------------------------------------------------- /plasticity/plasticity_VM_3D/quadrature_surface.m: -------------------------------------------------------------------------------- 1 | function [Xi_s, WF_s] = quadrature_surface(elem_type) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function specifies a numerical quadrature for surface integration, 5 | % depending on a chosen finite element. The quadratures suggested 6 | % below can be simply replaced by another ones. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % 11 | % output data: 12 | % Xi_s - local coordinates of quadrature points, size(Xi_s)=(2,n_q_s) 13 | % WF_s - weight factors, size(WF_s)=(1,n_q_s) 14 | %-------------------------------------------------------------------------- 15 | 16 | switch(elem_type) 17 | 18 | case 'P1' 19 | % - surface is created by the reference triangle with coordinates: 20 | % [0,0], [1,0], [0,1] 21 | % - 1-point quadrature rule, i.e., n_q_s=1 22 | Xi_s=[1/3; 1/3]; WF_s=1/2; 23 | 24 | case 'P2' 25 | % - surface is created by the reference triangle with coordinates: 26 | % [0,0], [1,0], [0,1] 27 | % - 3-point quadrature rule, i.e., n_q_s=3 28 | Xi_s=[1/6, 1/6, 2/3 29 | 1/6, 2/3, 1/6]; 30 | WF_s=[1/6, 1/6, 1/6]; 31 | 32 | case 'Q1' 33 | % - surface is created by the reference square with coordinates: 34 | % [-1,-1], [1,-1], [1,1], [-1,1] 35 | % - (2x2)-point quadrature rule, i.e., n_q_s=4 36 | pt = 1/sqrt(3); 37 | Xi_s=[-pt,-pt, pt, pt 38 | -pt, pt,-pt, pt]; 39 | WF_s=[1,1,1,1]; 40 | 41 | case 'Q2' 42 | % - surface is created by the reference square with coordinates: 43 | % [-1,-1], [1,-1], [1,1], [-1,1] 44 | % - (2x2)-point quadrature rule, i.e., n_q_s=4 45 | pt = 1/sqrt(3); 46 | Xi_s=[-pt,-pt, pt, pt 47 | -pt, pt,-pt, pt]; 48 | WF_s=[1,1,1,1]; 49 | 50 | otherwise; disp('Bad choise of element type'); 51 | end 52 | -------------------------------------------------------------------------------- /plasticity/plasticity_VM_3D/quadrature_volume.m: -------------------------------------------------------------------------------- 1 | function [Xi, WF] = quadrature_volume(elem_type) 2 | 3 | %-------------------------------------------------------------------------- 4 | % This function specifies a numerical quadrature for volume integration, 5 | % depending on a chosen finite element. The quadratures suggested 6 | % below can be simply replaced by another ones. 7 | % 8 | % input data: 9 | % elem_type - the type of Lagrange finite elements 10 | % 11 | % output data: 12 | % Xi - local coordinates of quadrature points, size(Xi)=(3,n_q) 13 | % WF - weight factors, size(WF)=(1,n_q) 14 | %-------------------------------------------------------------------------- 15 | 16 | switch(elem_type) 17 | 18 | case 'P1' 19 | % - the reference tetrahedron with coordinates: 20 | % [0,0,0], [1,0,0], [0,1,0], [0,0,1] 21 | % - 1-point quadrature rule, i.e., n_q=1 22 | Xi=[1/4; 1/4; 1/4]; WF=1/6; 23 | 24 | case 'P2' 25 | % - the reference tetrahedron with coordinates: 26 | % [0,0,0], [1,0,0], [0,1,0], [0,0,1] 27 | % - 11-point quadrature rule, i.e., n_q=11 28 | Xi=[1/4, 0.0714285714285714, 0.785714285714286, 0.0714285714285714, 0.0714285714285714, 0.399403576166799, 0.100596423833201, 0.100596423833201, 0.399403576166799, 0.399403576166799, 0.100596423833201 29 | 1/4, 0.0714285714285714, 0.0714285714285714, 0.785714285714286, 0.0714285714285714, 0.100596423833201, 0.399403576166799, 0.100596423833201, 0.399403576166799, 0.100596423833201, 0.399403576166799 30 | 1/4, 0.0714285714285714, 0.0714285714285714, 0.0714285714285714, 0.785714285714286, 0.100596423833201, 0.100596423833201, 0.399403576166799, 0.100596423833201, 0.399403576166799, 0.399403576166799]; 31 | WF=[-0.013155555555555, 0.007622222222222*ones(1,4), 0.024888888888888*ones(1,6)]; 32 | 33 | case 'Q1' 34 | % - the reference cube with coordinates: 35 | % [-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1], 36 | % [-1,-1,1], [1,-1,1], [1,1,1], [-1,1,1] 37 | % - (2x2x2)-point quadrature rule, i.e., n_q=8 38 | pt = 1/sqrt(3); 39 | Xi=[-pt,-pt,-pt,-pt, pt, pt, pt, pt 40 | -pt,-pt, pt, pt,-pt,-pt, pt, pt 41 | -pt, pt,-pt, pt,-pt, pt,-pt, pt]; 42 | WF=[1,1,1,1,1,1,1,1]; 43 | 44 | case 'Q2' 45 | % - the reference cube with coordinates: 46 | % [-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1], 47 | % [-1,-1,1], [1,-1,1], [1,1,1], [-1,1,1] 48 | % - (3x3x3)-point quadrature rule, i.e., n_q=27 49 | pt = sqrt(3/5); 50 | Xi=[-pt,-pt,-pt,-pt,-pt,-pt,-pt,-pt,-pt, 0, 0, 0, 0, 0, 0, 0, 0, 0, pt, pt, pt, pt, pt, pt, pt, pt, pt 51 | -pt,-pt,-pt, 0, 0, 0, pt, pt, pt,-pt,-pt,-pt, 0, 0, 0, pt, pt, pt,-pt,-pt,-pt, 0, 0, 0, pt, pt, pt 52 | -pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt,-pt, 0, pt]; 53 | WF= ((5/9)^3)* [1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1] +... 54 | ((5/9)^2)*(8/9)* [0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0] +... 55 | ((8/9)^2)*(5/9)* [0 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0] +... 56 | ((8/9)^3)* [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0]; 57 | 58 | otherwise; disp('Bad choice of element type'); 59 | end 60 | -------------------------------------------------------------------------------- /plasticity/plasticity_VM_3D/transformation.m: -------------------------------------------------------------------------------- 1 | % 2 | function Q_node=transformation(Q_int,elem,weight) 3 | 4 | % ====================================================================== 5 | % 6 | % Transformation of function values at integration points to function 7 | % values at nodes of the finite element mesh. 8 | % 9 | % output: 10 | % Q_node - values of a function Q at nodes of the FE mesh, 11 | % size(Q_node)=(1,n_n), where n_n is the number of nodes 12 | % 13 | % input data: 14 | % Q_int - values of a function Q at integration points, size(Q_int)=(1,n_int) 15 | % elem - to indicate nodes belonging to each element 16 | % size(elem)=(n_p,n_e) where n_e is a number of elements 17 | % and n_p is a number of the nodes within one element 18 | % weight - weight factors at integration points, size(weight)=(1,n_int) 19 | % 20 | % ========================================================================= 21 | 22 | % 23 | % Auxilliary notation 24 | % 25 | n_e=size(elem,2); % number of elements 26 | n_p=size(elem,1); % number of vertices per element 27 | n_int=length(weight); % total number of integrations points 28 | n_q=n_int/n_e; % number of quadrature points on one element 29 | 30 | % 31 | % F1 - 1*n_n array, to each node we compute numerically the integral of Q 32 | % through a vicinity of the node 33 | % F2 - 1*n_n array, to each node we compute the area of the vicinity 34 | % 35 | 36 | % values at integration points, size(vF1)=size(vF2)=(n_p,n_int) 37 | vF1 = ones(n_p,1)*(weight.*Q_int); 38 | vF2 = ones(n_p,1)*weight; 39 | 40 | % row and column indices, size(iF)=size(jF)=(n_p,n_int) 41 | iF = ones(n_p,n_int); 42 | jF = kron(elem,ones(1,n_q)); 43 | 44 | % the asssembling by using the sparse command - values v for duplicate 45 | % doubles i,j are automatically added together 46 | F1 = sparse(iF(:), jF(:), vF1(:)) ; 47 | F2 = sparse(iF(:), jF(:), vF2(:)) ; 48 | 49 | % 50 | % Approximated values of the function Q at nodes of the FE mesh 51 | % 52 | Q_node = F1./F2; 53 | 54 | --------------------------------------------------------------------------------