├── GenerateVoxel.m ├── README.md ├── homo3D.m ├── image ├── 1.jpg └── homogenization.JPG ├── topology ├── Star.txt ├── face_center.txt ├── grid.txt ├── grid_octet.txt ├── octet.txt ├── tesseract.txt ├── vintiles.txt ├── x.txt └── x_cross_grid.txt ├── transform.m └── visual.m /GenerateVoxel.m: -------------------------------------------------------------------------------- 1 | function [voxel,Density] = GenerateVoxel(n,address,radius) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % n is the number of voxel along each axis 4 | % address is the file location of wireframe 5 | % density is the relative density 6 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7 | size = 1/n; % initial size of voxels 8 | voxel = zeros(n,n,n); % initial grid with zeros 9 | %% generate a list of centers of voxel 10 | voxel_c = zeros(n^3,6); 11 | p = 0; % p count the number of all voxels 12 | for i = 1:n % i for z axis 13 | for j = 1:n % j for y axis 14 | for k = 1:n % k for x axis 15 | p = p + 1; 16 | voxel_c(p,1:3) = [k,j,i]; % save index along x,y,z axis 17 | % save coordinate along x,y,z axis 18 | voxel_c(p,4:6) = [(k-0.5)*size,(j-0.5)*size,(i-0.5)*size]; 19 | end 20 | end 21 | end 22 | %% Get the voxel close the the strut witnin a certain distance 23 | [node,strut] = ReadStrut(address); % get the information of strut 24 | for i = 1:length(voxel_c) % for each voxel, deside if it is active 25 | % for each strut, get the distance to the voxel 26 | for j = 1:length(strut) 27 | start_n = node(strut(j,1),:); % start node coordinate 28 | end_n = node(strut(j,2),:); % end node coordinate 29 | center = voxel_c(i,4:6); % voxel center position 30 | % determine alpha and beta are acute angle 31 | alpha = acosd(((center - start_n)*(end_n - start_n)')... 32 | /(norm(center - start_n)*norm(end_n - start_n))); 33 | beta = acosd(((center - end_n)*(start_n - end_n)')... 34 | /(norm(center - end_n)*norm(start_n - end_n))); 35 | if(alpha<90 && beta<90)% if not acute angle, distance to line 36 | distance = norm(cross(end_n - start_n,center - start_n))... 37 | /norm(end_n - start_n); 38 | else % if it is acute angle, distance to node 39 | distance = min(norm(center - start_n),norm(center - end_n)); 40 | end 41 | if (distance<=radius) % if distance less than radius, active it 42 | voxel(voxel_c(i,1),voxel_c(i,2),voxel_c(i,3)) = 1; 43 | continue; % run for the next voxel 44 | end 45 | end 46 | end 47 | Density = sum(sum(sum(voxel)))/n^3;% calculate the relative density 48 | end 49 | %%Import information of strut 50 | function [nodelist,strutlist] = ReadStrut(address) 51 | fid = fopen(address,'r'); 52 | k = 1; 53 | j = 1; 54 | tline = fgetl(fid); 55 | while ischar(tline) 56 | if (tline(1) == 'G') 57 | x = str2double(tline(17:24)); 58 | y = str2double(tline(25:32)); 59 | z = str2double(tline(33:40)); 60 | nodelist(k,1:3) = [x,y,z]; 61 | k = k + 1; 62 | end 63 | if (tline(1) == 'S') 64 | Snode = str2double(tline(17:24)); 65 | Enode = str2double(tline(25:32)); 66 | strutlist(j,1:2) = [Snode,Enode]; 67 | j = j + 1; 68 | end 69 | tline = fgetl(fid); 70 | end 71 | fclose(fid); 72 | end 73 | 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Update: 2 | The code is updated on 05/27/2025 to fix a problem for heterogeneous structures. The B_e matrix is updated to fix the inconsistency of xx,yy,zz,yz,xz,xy. 3 | # homogenization 4 | Please cite the following article if you use this code in your publications: 5 | 6 | Dong G, Tang Y, Zhao Y. A 149 Line Homogenization Code for Three-Dimensional Cellular Materials Written in matlab. ASME. J. Eng. Mater. Technol. 2018;141(1):011005-011005-11. doi:10.1115/1.4040555. 7 | 8 | Homogenization code for 3D lattice structure. For more information you can visit http://www.intralatticepro.com/ 9 | 10 | ![alt text](https://github.com/GuoyingDong/homogenization/blob/master/image/homogenization.JPG) 11 | 12 | "homo3d.m" is to calculate the homogenized material property of 3d lattice structures. 13 | 14 | "GenerateVoxel.m" is to generate the voxel model for homo3d.m. 15 | 16 | "visual.m" is to plot the 3D Young's modulus surface indicating E along all directions. 17 | 18 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 19 | 20 | To use homo3d.m : 21 | 22 | CH = homo3D(lx,ly,lz,lambda,mu,voxel); 23 | 24 | % lx = Unit cell length in x-direction. 25 | 26 | % ly = Unit cell length in y-direction. 27 | 28 | % lz = Unit cell length in z-direction. 29 | 30 | % lambda = Lame's first parameter for solid materials. 31 | 32 | % mu = Lame's second parameter for solid materials. 33 | 34 | % voxel = Material indicator matrix. 35 | 36 | % lambda = vE/(1+v)(1-2v), mu = E/2(1+v), E is Young's modulus, v is Poisson's ratio 37 | 38 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 39 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 40 | 41 | To use GenerateVoxel.m : 42 | 43 | [voxel,Density] = GenerateVoxel(n,address,radius); 44 | 45 | % n = the number of voxel along each axis. 46 | 47 | % address = the file location of wireframe. 48 | 49 | % radius = the radius of the lattice structure. 50 | 51 | % Density = the relative density of the lattices. 52 | 53 | The predifined wireframe file can be found in the topology folder. 54 | 55 | The length of the unit cell is 1. 56 | 57 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 58 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 59 | 60 | To use visual.m : 61 | 62 | visual(CH); 63 | 64 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 65 | 66 | Example: 67 | 68 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 69 | 70 | [voxel,Density] = GenerateVoxel(40,'topology/grid.txt',0.1); 71 | 72 | CH = homo3D(1,1,1,115.4,79.6,voxel); 73 | 74 | visual(CH) 75 | 76 | % the topology is 'grid', the model has 40 voxels along each axis. 77 | 78 | % the radius is 0.1, the length of the unit cell is 1 as defined. 79 | 80 | % lambda = 115.4, mu = 79.6, whcih is equivalent to E = 200, v= 0.3. 81 | 82 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 83 | 84 | The result is: 85 | 86 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 | 88 | Density = 8.5% 89 | 90 | CH = 91 | 92 | 7.1876 0.3875 0.3875 0.0000 -0.0000 0.0000 93 | 94 | 0.3875 7.1876 0.3875 -0.0000 0.0000 0.0000 95 | 96 | 0.3875 0.3875 7.1876 -0.0000 -0.0000 -0.0000 97 | 98 | 0.0000 -0.0000 -0.0000 0.1489 0.0000 0.0000 99 | 100 | 0.0000 0.0000 -0.0000 0.0000 0.1489 -0.0000 101 | 102 | 0.0000 0.0000 -0.0000 0.0000 -0.0000 0.1489 103 | 104 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 105 | 106 | The Young's modulus surface: 107 | 108 | ![alt text](https://github.com/GuoyingDong/homogenization/blob/master/image/1.jpg) 109 | -------------------------------------------------------------------------------- /homo3D.m: -------------------------------------------------------------------------------- 1 | function CH = homo3D(lx,ly,lz,lambda,mu,voxel) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % lx = Unit cell length in x-direction. 4 | % ly = Unit cell length in y-direction. 5 | % lz = Unit cell length in z-direction. 6 | % lambda = Lame's first parameter for solid materials. 7 | % mu = Lame's second parameter for solid materials. 8 | % voxel = Material indicator matrix. Used to determine nelx/nely/nelz 9 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10 | %% INITIALIZE 11 | [nelx, nely, nelz] = size(voxel); %size of voxel model along x,y and z axis 12 | % Stiffness matrix 13 | dx = lx/nelx; dy = ly/nely; dz = lz/nelz; 14 | nel = nelx*nely*nelz; 15 | [keLambda, keMu, feLambda, feMu] = hexahedron(dx/2,dy/2,dz/2); 16 | % Node numbers and element degrees of freedom for full (not periodic) mesh 17 | nodenrs = reshape(1:(1+nelx)*(1+nely)*(1+nelz),1+nelx,1+nely,1+nelz); 18 | edofVec = reshape(3*nodenrs(1:end-1,1:end-1,1:end-1)+1,nel,1); 19 | addx = [0 1 2 3*nelx+[3 4 5 0 1 2] -3 -2 -1]; 20 | addxy = 3*(nely+1)*(nelx+1)+addx; 21 | edof = repmat(edofVec,1,24) + repmat([addx addxy],nel,1); 22 | %% IMPOOSE PERIODIC BOUNDARY CONDITIONS 23 | % Use original edofMat to index into list with the periodic dofs 24 | nn = (nelx+1)*(nely+1)*(nelz+1); % Total number of nodes 25 | nnP = (nelx)*(nely)*(nelz); % Total number of unique nodes 26 | nnPArray = reshape(1:nnP, nelx, nely, nelz); 27 | % Extend with a mirror of the back border 28 | nnPArray(end+1,:,:) = nnPArray(1,:,:); 29 | % Extend with a mirror of the left border 30 | nnPArray(:, end+1, :) = nnPArray(:,1,:); 31 | % Extend with a mirror of the top border 32 | nnPArray(:, :, end+1) = nnPArray(:,:,1); 33 | % Make a vector into which we can index using edofMat: 34 | dofVector = zeros(3*nn, 1); 35 | dofVector(1:3:end) = 3*nnPArray(:)-2; 36 | dofVector(2:3:end) = 3*nnPArray(:)-1; 37 | dofVector(3:3:end) = 3*nnPArray(:); 38 | edof = dofVector(edof); 39 | ndof = 3*nnP; 40 | %% ASSEMBLE GLOBAL STIFFNESS MATRIX AND LOAD VECTORS 41 | % Indexing vectors 42 | iK = kron(edof,ones(24,1))'; 43 | jK = kron(edof,ones(1,24))'; 44 | % Material properties assigned to voxels with materials 45 | lambda = lambda*(voxel==1); mu = mu*(voxel==1); 46 | % The corresponding stiffness matrix entries 47 | sK = keLambda(:)*lambda(:).' + keMu(:)*mu(:).'; 48 | K = sparse(iK(:), jK(:), sK(:), ndof, ndof); 49 | K = 1/2*(K+K'); 50 | % Assembly three load cases corresponding to the three strain cases 51 | iF = repmat(edof',6,1); 52 | jF = [ones(24,nel); 2*ones(24,nel); 3*ones(24,nel);... 53 | 4*ones(24,nel); 5*ones(24,nel); 6*ones(24,nel);]; 54 | sF = feLambda(:)*lambda(:).'+feMu(:)*mu(:).'; 55 | F = sparse(iF(:), jF(:), sF(:), ndof, 6); 56 | %% SOLUTION 57 | % solve by PCG method, remember to constrain one node 58 | activedofs = edof(voxel==1,:); activedofs = sort(unique(activedofs(:))); 59 | X = zeros(ndof,6); 60 | L = ichol(K(activedofs(4:end),activedofs(4:end))); 61 | for i = 1:6 62 | X(activedofs(4:end),i) = pcg(K(activedofs(4:end),... 63 | activedofs(4:end)),F(activedofs(4:end),i),1e-10,300,L,L'); 64 | end 65 | % X(activedofs(4:end),:) = K(activedofs(4:end),activedofs(4:end))... 66 | % \F(activedofs(4:end),:); % Solving by direct method 67 | %% HOMOGENIZATION 68 | % The displacement vectors corresponding to the unit strain cases 69 | X0 = zeros(nel, 24, 6); 70 | % The element displacements for the six unit strains 71 | X0_e = zeros(24, 6); 72 | %fix degrees of nodes [1 2 3 5 6 12]; 73 | ke = keMu + keLambda; % Here the exact ratio does not matter, because 74 | fe = feMu + feLambda; % it is reflected in the load vector 75 | X0_e([4 7:11 13:24],:) = ke([4 7:11 13:24],[4 7:11 13:24])... 76 | \fe([4 7:11 13:24],:); 77 | X0(:,:,1) = kron(X0_e(:,1)', ones(nel,1)); % epsilon0_11 = (1,0,0,0,0,0) 78 | X0(:,:,2) = kron(X0_e(:,2)', ones(nel,1)); % epsilon0_22 = (0,1,0,0,0,0) 79 | X0(:,:,3) = kron(X0_e(:,3)', ones(nel,1)); % epsilon0_33 = (0,0,1,0,0,0) 80 | X0(:,:,4) = kron(X0_e(:,4)', ones(nel,1)); % epsilon0_12 = (0,0,0,1,0,0) 81 | X0(:,:,5) = kron(X0_e(:,5)', ones(nel,1)); % epsilon0_23 = (0,0,0,0,1,0) 82 | X0(:,:,6) = kron(X0_e(:,6)', ones(nel,1)); % epsilon0_13 = (0,0,0,0,0,1) 83 | CH = zeros(6); 84 | volume = lx*ly*lz; 85 | for i = 1:6 86 | for j = 1:6 87 | sum_L = ((X0(:,:,i) - X(edof+(i-1)*ndof))*keLambda).*... 88 | (X0(:,:,j) - X(edof+(j-1)*ndof)); 89 | sum_M = ((X0(:,:,i) - X(edof+(i-1)*ndof))*keMu).*... 90 | (X0(:,:,j) - X(edof+(j-1)*ndof)); 91 | sum_L = reshape(sum(sum_L,2), nelx, nely, nelz); 92 | sum_M = reshape(sum(sum_M,2), nelx, nely, nelz); 93 | % Homogenized elasticity tensor 94 | CH(i,j) = 1/volume*sum(sum(sum(lambda.*sum_L + mu.*sum_M))); 95 | end 96 | end 97 | end 98 | %% COMPUTE ELEMENT STIFFNESS MATRIX AND LOAD VECTOR 99 | function [keLambda, keMu, feLambda, feMu] = hexahedron(a, b, c) 100 | % Constitutive matrix contributions 101 | CMu = diag([2 2 2 1 1 1]); CLambda = zeros(6); CLambda(1:3,1:3) = 1; 102 | % Three Gauss points in both directions 103 | xx = [-sqrt(3/5), 0, sqrt(3/5)]; yy = xx; zz = xx; 104 | ww = [5/9, 8/9, 5/9]; 105 | % Initialize 106 | keLambda = zeros(24,24); keMu = zeros(24,24); 107 | feLambda = zeros(24,6); feMu = zeros(24,6); 108 | for ii = 1:length(xx) 109 | for jj = 1:length(yy) 110 | for kk = 1:length(zz) 111 | %integration point 112 | x = xx(ii); y = yy(jj); z = zz(kk); 113 | %stress strain displacement matrix 114 | qx = [ -((y-1)*(z-1))/8, ((y-1)*(z-1))/8, -((y+1)*(z-1))/8,... 115 | ((y+1)*(z-1))/8, ((y-1)*(z+1))/8, -((y-1)*(z+1))/8,... 116 | ((y+1)*(z+1))/8, -((y+1)*(z+1))/8]; 117 | qy = [ -((x-1)*(z-1))/8, ((x+1)*(z-1))/8, -((x+1)*(z-1))/8,... 118 | ((x-1)*(z-1))/8, ((x-1)*(z+1))/8, -((x+1)*(z+1))/8,... 119 | ((x+1)*(z+1))/8, -((x-1)*(z+1))/8]; 120 | qz = [ -((x-1)*(y-1))/8, ((x+1)*(y-1))/8, -((x+1)*(y+1))/8,... 121 | ((x-1)*(y+1))/8, ((x-1)*(y-1))/8, -((x+1)*(y-1))/8,... 122 | ((x+1)*(y+1))/8, -((x-1)*(y+1))/8]; 123 | % Jacobian 124 | J = [qx; qy; qz]*[-a a a -a -a a a -a; -b -b b b -b -b b b;... 125 | -c -c -c -c c c c c]'; 126 | qxyz = J\[qx;qy;qz]; 127 | B_e = zeros(6,3,8); 128 | for i_B = 1:8 129 | B_e(:,:,i_B) = [qxyz(1,i_B) 0 0; 130 | 0 qxyz(2,i_B) 0; 131 | 0 0 qxyz(3,i_B); 132 | 0 qxyz(3,i_B) qxyz(2,i_B); 133 | qxyz(3,i_B) 0 qxyz(1,i_B); 134 | qxyz(2,i_B) qxyz(1,i_B) 0]; 135 | end 136 | B = [B_e(:,:,1) B_e(:,:,2) B_e(:,:,3) B_e(:,:,4) B_e(:,:,5)... 137 | B_e(:,:,6) B_e(:,:,7) B_e(:,:,8)]; 138 | % Weight factor at this point 139 | weight = det(J)*ww(ii) * ww(jj) * ww(kk); 140 | % Element matrices 141 | keLambda = keLambda + weight * B' * CLambda * B; 142 | keMu = keMu + weight * B' * CMu * B; 143 | % Element loads 144 | feLambda = feLambda + weight * B' * CLambda; 145 | feMu = feMu + weight * B' * CMu; 146 | end 147 | end 148 | end 149 | end -------------------------------------------------------------------------------- /image/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuoyingDong/homogenization/5ea42db70de218257ca75807036b715128430fcd/image/1.jpg -------------------------------------------------------------------------------- /image/homogenization.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuoyingDong/homogenization/5ea42db70de218257ca75807036b715128430fcd/image/homogenization.JPG -------------------------------------------------------------------------------- /topology/Star.txt: -------------------------------------------------------------------------------- 1 | //Grid ID x y z 2 | GRID 1 0 0 0 3 | GRID 2 1 0 0 4 | GRID 3 0 1 0 5 | GRID 4 0 0 1 6 | GRID 5 0.5 0.5 0.5 7 | GRID 6 1 1 1 8 | GRID 7 0 1 1 9 | GRID 8 1 0 1 10 | GRID 9 1 1 0 11 | //Strut ID Start End 12 | STRUT 1 1 2 13 | STRUT 2 1 3 14 | STRUT 3 1 4 15 | STRUT 4 1 5 16 | STRUT 5 5 6 17 | STRUT 6 2 5 18 | STRUT 7 5 7 19 | STRUT 8 3 5 20 | STRUT 9 5 8 21 | STRUT 10 9 5 22 | STRUT 11 5 4 23 | STRUT 12 4 8 24 | STRUT 13 4 7 25 | STRUT 14 3 9 26 | STRUT 15 3 7 27 | STRUT 16 7 6 28 | STRUT 17 2 9 29 | STRUT 18 2 8 30 | STRUT 19 8 6 31 | STRUT 20 9 6 32 | -------------------------------------------------------------------------------- /topology/face_center.txt: -------------------------------------------------------------------------------- 1 | //Grid ID x y z 2 | GRID 1 0 0 0 3 | GRID 2 0.5 0 0.5 4 | GRID 3 1 0 1 5 | GRID 4 1 0 0 6 | GRID 5 0 0 1 7 | GRID 6 0 0.5 0.5 8 | GRID 7 0 1 1 9 | GRID 8 0 1 0 10 | GRID 9 0.5 0.5 0 11 | GRID 10 1 1 0 12 | GRID 11 0.5 0.5 1 13 | GRID 12 1 1 1 14 | GRID 13 0.5 1 0.5 15 | GRID 14 1 0.5 0.5 16 | //Strut ID Start End 17 | STRUT 1 1 2 18 | STRUT 2 2 3 19 | STRUT 3 4 2 20 | STRUT 4 2 5 21 | STRUT 5 1 6 22 | STRUT 6 6 7 23 | STRUT 7 8 6 24 | STRUT 8 6 5 25 | STRUT 9 1 9 26 | STRUT 10 9 10 27 | STRUT 11 4 9 28 | STRUT 12 9 8 29 | STRUT 13 5 11 30 | STRUT 14 11 12 31 | STRUT 15 3 11 32 | STRUT 16 11 7 33 | STRUT 17 8 13 34 | STRUT 18 13 12 35 | STRUT 19 10 13 36 | STRUT 20 13 7 37 | STRUT 21 4 14 38 | STRUT 22 14 12 39 | STRUT 23 10 14 40 | STRUT 24 14 3 41 | STRUT 25 1 4 42 | STRUT 26 1 8 43 | STRUT 27 1 5 44 | STRUT 28 5 3 45 | STRUT 29 5 7 46 | STRUT 30 8 10 47 | STRUT 31 8 7 48 | STRUT 32 7 12 49 | STRUT 33 4 10 50 | STRUT 34 4 3 51 | STRUT 35 3 12 52 | STRUT 36 10 12 53 | -------------------------------------------------------------------------------- /topology/grid.txt: -------------------------------------------------------------------------------- 1 | //Grid ID x y z 2 | GRID 1 0 0 0 3 | GRID 2 1 0 0 4 | GRID 3 0 1 0 5 | GRID 4 0 0 1 6 | GRID 5 1 0 1 7 | GRID 6 0 1 1 8 | GRID 7 1 1 0 9 | GRID 8 1 1 1 10 | //Strut ID Start End 11 | STRUT 1 1 2 12 | STRUT 2 1 3 13 | STRUT 3 1 4 14 | STRUT 4 4 5 15 | STRUT 5 4 6 16 | STRUT 6 3 7 17 | STRUT 7 3 6 18 | STRUT 8 6 8 19 | STRUT 9 2 7 20 | STRUT 10 2 5 21 | STRUT 11 5 8 22 | STRUT 12 7 8 23 | -------------------------------------------------------------------------------- /topology/grid_octet.txt: -------------------------------------------------------------------------------- 1 | //Grid ID x y z 2 | GRID 1 0.5 0.5 0 3 | GRID 2 0 0 0 4 | GRID 3 1 0 0 5 | GRID 4 1 1 0 6 | GRID 5 0 1 0 7 | GRID 6 1 0.5 0.5 8 | GRID 7 0.5 1 0.5 9 | GRID 8 0 0.5 0.5 10 | GRID 9 0.5 0 0.5 11 | GRID 10 0.5 0.5 1 12 | GRID 11 0 0 1 13 | GRID 12 0 1 1 14 | GRID 13 1 0 1 15 | GRID 14 1 1 1 16 | //Strut ID Start End 17 | STRUT 1 1 2 18 | STRUT 2 1 3 19 | STRUT 3 1 4 20 | STRUT 4 1 5 21 | STRUT 5 1 6 22 | STRUT 6 1 7 23 | STRUT 7 1 8 24 | STRUT 8 1 9 25 | STRUT 9 10 6 26 | STRUT 10 10 7 27 | STRUT 11 10 8 28 | STRUT 12 10 9 29 | STRUT 13 8 2 30 | STRUT 14 8 5 31 | STRUT 15 8 11 32 | STRUT 16 8 12 33 | STRUT 17 7 6 34 | STRUT 18 7 8 35 | STRUT 19 9 2 36 | STRUT 20 9 3 37 | STRUT 21 9 11 38 | STRUT 22 9 13 39 | STRUT 23 9 6 40 | STRUT 24 9 8 41 | STRUT 25 10 11 42 | STRUT 26 10 13 43 | STRUT 27 10 14 44 | STRUT 28 10 12 45 | STRUT 29 7 5 46 | STRUT 30 7 4 47 | STRUT 31 7 12 48 | STRUT 32 7 14 49 | STRUT 33 6 3 50 | STRUT 34 6 4 51 | STRUT 35 6 13 52 | STRUT 36 6 14 53 | STRUT 37 2 3 54 | STRUT 38 2 5 55 | STRUT 39 2 11 56 | STRUT 40 11 13 57 | STRUT 41 11 12 58 | STRUT 42 5 4 59 | STRUT 43 5 12 60 | STRUT 44 12 14 61 | STRUT 45 3 4 62 | STRUT 46 3 13 63 | STRUT 47 13 14 64 | STRUT 48 4 14 65 | -------------------------------------------------------------------------------- /topology/octet.txt: -------------------------------------------------------------------------------- 1 | //Grid ID x y z 2 | GRID 1 0.5 0.5 0 3 | GRID 2 0 0 0 4 | GRID 3 1 0 0 5 | GRID 4 1 1 0 6 | GRID 5 0 1 0 7 | GRID 6 1 0.5 0.5 8 | GRID 7 0.5 1 0.5 9 | GRID 8 0 0.5 0.5 10 | GRID 9 0.5 0 0.5 11 | GRID 10 0.5 0.5 1 12 | GRID 11 0 0 1 13 | GRID 12 0 1 1 14 | GRID 13 1 0 1 15 | GRID 14 1 1 1 16 | //Strut ID Start End 17 | STRUT 1 1 2 18 | STRUT 2 1 3 19 | STRUT 3 1 4 20 | STRUT 4 1 5 21 | STRUT 5 1 6 22 | STRUT 6 1 7 23 | STRUT 7 1 8 24 | STRUT 8 1 9 25 | STRUT 9 10 6 26 | STRUT 10 10 7 27 | STRUT 11 10 8 28 | STRUT 12 10 9 29 | STRUT 13 8 2 30 | STRUT 14 8 5 31 | STRUT 15 8 11 32 | STRUT 16 8 12 33 | STRUT 17 7 6 34 | STRUT 18 7 8 35 | STRUT 19 9 2 36 | STRUT 20 9 3 37 | STRUT 21 9 11 38 | STRUT 22 9 13 39 | STRUT 23 9 6 40 | STRUT 24 9 8 41 | STRUT 25 10 11 42 | STRUT 26 10 13 43 | STRUT 27 10 14 44 | STRUT 28 10 12 45 | STRUT 29 7 5 46 | STRUT 30 7 4 47 | STRUT 31 7 12 48 | STRUT 32 7 14 49 | STRUT 33 6 3 50 | STRUT 34 6 4 51 | STRUT 35 6 13 52 | STRUT 36 6 14 53 | -------------------------------------------------------------------------------- /topology/tesseract.txt: -------------------------------------------------------------------------------- 1 | //Grid ID x y z 2 | GRID 1 0 0 0 3 | GRID 2 1 0 0 4 | GRID 3 0.25 0.25 0.25 5 | GRID 4 0.75 0.25 0.25 6 | GRID 5 0 1 0 7 | GRID 6 0.25 0.75 0.25 8 | GRID 7 0 0 1 9 | GRID 8 0.25 0.25 0.75 10 | GRID 9 0.75 0.75 0.25 11 | GRID 10 0.75 0.75 0.75 12 | GRID 11 0.75 0.25 0.75 13 | GRID 12 0.25 0.75 0.75 14 | GRID 13 1 1 0 15 | GRID 14 1 0 1 16 | GRID 15 1 1 1 17 | GRID 16 0 1 1 18 | //Strut ID Start End 19 | STRUT 1 1 2 20 | STRUT 2 3 4 21 | STRUT 3 1 5 22 | STRUT 4 3 6 23 | STRUT 5 1 7 24 | STRUT 6 3 8 25 | STRUT 7 9 4 26 | STRUT 8 9 6 27 | STRUT 9 9 10 28 | STRUT 10 11 4 29 | STRUT 11 11 8 30 | STRUT 12 11 10 31 | STRUT 13 12 6 32 | STRUT 14 12 8 33 | STRUT 15 12 10 34 | STRUT 16 1 3 35 | STRUT 17 2 4 36 | STRUT 18 13 9 37 | STRUT 19 5 6 38 | STRUT 20 7 8 39 | STRUT 21 14 11 40 | STRUT 22 15 10 41 | STRUT 23 16 12 42 | STRUT 24 7 14 43 | STRUT 25 7 16 44 | STRUT 26 5 13 45 | STRUT 27 5 16 46 | STRUT 28 16 15 47 | STRUT 29 2 13 48 | STRUT 30 2 14 49 | STRUT 31 14 15 50 | STRUT 32 13 15 51 | -------------------------------------------------------------------------------- /topology/vintiles.txt: -------------------------------------------------------------------------------- 1 | //Grid ID x y z 2 | GRID 1 0 0.5 0.25 3 | GRID 2 0 0.25 0 4 | GRID 3 0 0.75 0 5 | GRID 4 0.25 0.5 0.5 6 | GRID 5 0.5 1 0.25 7 | GRID 6 0.5 0.75 0.5 8 | GRID 7 1 0.5 0.25 9 | GRID 8 0.75 0.5 0.5 10 | GRID 9 0.5 0 0.25 11 | GRID 10 0.75 0 0 12 | GRID 11 0.25 0 0 13 | GRID 12 0.5 0.25 0.5 14 | GRID 13 0 0.5 0.75 15 | GRID 14 0 0.25 1 16 | GRID 15 0 0.75 1 17 | GRID 16 0.5 1 0.75 18 | GRID 17 1 0.5 0.75 19 | GRID 18 0.5 0 0.75 20 | GRID 19 0.75 0 1 21 | GRID 20 0.25 0 1 22 | GRID 21 0.25 1 0 23 | GRID 22 0.75 1 0 24 | GRID 23 1 0.75 0 25 | GRID 24 1 0.25 0 26 | GRID 25 0.25 1 1 27 | GRID 26 0.75 1 1 28 | GRID 27 1 0.75 1 29 | GRID 28 1 0.25 1 30 | //Strut ID Start End 31 | STRUT 1 1 2 32 | STRUT 2 1 3 33 | STRUT 3 1 4 34 | STRUT 4 5 6 35 | STRUT 5 7 8 36 | STRUT 6 9 10 37 | STRUT 7 9 11 38 | STRUT 8 9 12 39 | STRUT 9 13 14 40 | STRUT 10 13 15 41 | STRUT 11 13 4 42 | STRUT 12 16 6 43 | STRUT 13 17 8 44 | STRUT 14 18 19 45 | STRUT 15 18 20 46 | STRUT 16 18 12 47 | STRUT 17 3 21 48 | STRUT 18 22 23 49 | STRUT 19 24 10 50 | STRUT 20 4 12 51 | STRUT 21 8 12 52 | STRUT 22 4 6 53 | STRUT 23 8 6 54 | STRUT 24 2 11 55 | STRUT 25 15 25 56 | STRUT 26 26 27 57 | STRUT 27 28 19 58 | STRUT 28 14 20 59 | STRUT 29 5 22 60 | STRUT 30 5 21 61 | STRUT 31 16 26 62 | STRUT 32 16 25 63 | STRUT 33 7 24 64 | STRUT 34 7 23 65 | STRUT 35 17 28 66 | STRUT 36 17 27 67 | -------------------------------------------------------------------------------- /topology/x.txt: -------------------------------------------------------------------------------- 1 | //Grid ID x y z 2 | GRID 1 0 0 0 3 | GRID 2 0.5 0.5 0.5 4 | GRID 3 1 1 1 5 | GRID 4 1 0 0 6 | GRID 5 0 1 1 7 | GRID 6 0 1 0 8 | GRID 7 1 0 1 9 | GRID 8 1 1 0 10 | GRID 9 0 0 1 11 | //Strut ID Start End 12 | STRUT 1 1 2 13 | STRUT 2 2 3 14 | STRUT 3 4 2 15 | STRUT 4 2 5 16 | STRUT 5 6 2 17 | STRUT 6 2 7 18 | STRUT 7 8 2 19 | STRUT 8 2 9 20 | -------------------------------------------------------------------------------- /topology/x_cross_grid.txt: -------------------------------------------------------------------------------- 1 | //Grid ID x y z 2 | GRID 1 0 0 0 3 | GRID 2 0.5 0 0.5 4 | GRID 3 1 0 1 5 | GRID 4 1 0 0 6 | GRID 5 0 0 1 7 | GRID 6 0 0.5 0.5 8 | GRID 7 0 1 1 9 | GRID 8 0 1 0 10 | GRID 9 0.5 0.5 0 11 | GRID 10 1 1 0 12 | GRID 11 0.5 0.5 1 13 | GRID 12 1 1 1 14 | GRID 13 0.5 1 0.5 15 | GRID 14 1 0.5 0.5 16 | GRID 15 0.5 0.5 0.5 17 | //Strut ID Start End 18 | STRUT 1 1 2 19 | STRUT 2 2 3 20 | STRUT 3 4 2 21 | STRUT 4 2 5 22 | STRUT 5 1 6 23 | STRUT 6 6 7 24 | STRUT 7 8 6 25 | STRUT 8 6 5 26 | STRUT 9 1 9 27 | STRUT 10 9 10 28 | STRUT 11 4 9 29 | STRUT 12 9 8 30 | STRUT 13 5 11 31 | STRUT 14 11 12 32 | STRUT 15 3 11 33 | STRUT 16 11 7 34 | STRUT 17 8 13 35 | STRUT 18 13 12 36 | STRUT 19 10 13 37 | STRUT 20 13 7 38 | STRUT 21 4 14 39 | STRUT 22 14 12 40 | STRUT 23 10 14 41 | STRUT 24 14 3 42 | STRUT 25 1 4 43 | STRUT 26 1 8 44 | STRUT 27 1 5 45 | STRUT 28 5 3 46 | STRUT 29 5 7 47 | STRUT 30 8 10 48 | STRUT 31 8 7 49 | STRUT 32 7 12 50 | STRUT 33 4 10 51 | STRUT 34 4 3 52 | STRUT 35 3 12 53 | STRUT 36 10 12 54 | STRUT 37 1 15 55 | STRUT 38 15 12 56 | STRUT 39 4 15 57 | STRUT 40 15 7 58 | STRUT 41 8 15 59 | STRUT 42 15 3 60 | STRUT 43 10 15 61 | STRUT 44 15 5 62 | -------------------------------------------------------------------------------- /transform.m: -------------------------------------------------------------------------------- 1 | function otr = transform(itr,tmx) 2 | 3 | % 4 | % FUNCTION 5 | % otr = transform(itr,tmx) 6 | % 7 | % DESCRIPTION 8 | % transform 3D-tensor (Euclidean or Cartesion tensor) of any order (>0) to another coordinate system 9 | % 10 | % PARAMETERS 11 | % otr = output tensor, after transformation; has the same dimensions as the input tensor 12 | % itr = input tensor, before transformation; should be a 3-element vector, a 3x3 matrix, or a 3x3x3x... multidimensional array, each dimension containing 3 elements 13 | % tmx = transformation matrix, 3x3 matrix that contains the direction cosines between the old and the new coordinate system 14 | % 15 | 16 | ne = numel(itr); % number of tensor elements 17 | nd = ndims(itr); % number of tensor dimensions, i.e. order of tensor 18 | if (ne==3), nd = 1; end % order of tensor is 1 in case of a 3x1 or 1x3 vector 19 | 20 | otr = itr; % create output tensor 21 | otr(:) = 0; % fill output tensor with zeros; this way a symbolic tensor remains symbolic 22 | 23 | iie = zeros(nd,1); % initialise vector with indices of input tensor element 24 | ioe = zeros(nd,1); % initialise vector with indices of output tensor element 25 | cne = cumprod(3*ones(nd,1))/3; % vector with cumulative number of elements for each dimension (divided by three) 26 | 27 | for oe = 1:ne, % loop over all output elements 28 | ioe = mod(floor((oe-1)./cne),3)+1; % calculate indices of current output tensor element 29 | for ie = 1:ne, % loop over all input elements 30 | pmx = 1; % initialise product of transformation matrices 31 | iie = mod(floor((ie-1)./cne),3)+1; % calculate indices of current input tensor element 32 | for id = 1:nd, % loop over all dimensions 33 | pmx = pmx * tmx( ioe(id), iie(id) ); % create product of transformation matrices 34 | end 35 | otr(oe) = otr(oe) + pmx * itr(ie); % add product of transformation matrices and input tensor element to output tensor element 36 | end 37 | end 38 | 39 | % Transform matrix about Z axis 40 | % for x = 0:pi/20:pi/2 41 | % trans = [cos(x) cos(x-pi/2) 0; 42 | % cos(x+pi/2) cos(x) 0; 43 | % 0 0 1]; 44 | % N_CH = transform(C,trans); 45 | % end -------------------------------------------------------------------------------- /visual.m: -------------------------------------------------------------------------------- 1 | % input the homogenized elasticity tensor 2 | function [s] = visual(CH) 3 | % transform it to 3*3*3*3 tensor 4 | tensor = generate(CH); 5 | % find the E1 in 360 degree 6 | % x = 0:pi/180:2*pi; 7 | [a,e] = meshgrid(0:0.02*pi:2*pi, -pi/2:0.01*pi:pi/2); 8 | E1 = zeros(size(a)); 9 | for i = 1:size(a,1) 10 | for j = 1:size(a,2) 11 | % build the transformation matrix 12 | trans_z = [cos(a(i,j)) -sin(a(i,j)) 0; 13 | sin(a(i,j)) cos(a(i,j)) 0; 14 | 0 0 1]; 15 | trans_y = [cos(e(i,j)) 0 sin(e(i,j)); 16 | 0 1 0; 17 | -sin(e(i,j)) 0 cos(e(i,j))]; 18 | % calculate the new tensor 19 | N_tensor = transform(tensor,trans_y*trans_z); 20 | % transform the tensor to 6*6 21 | N_CH = ToMatrix(N_tensor); 22 | % calculate the E1 23 | E = modulus(N_CH); 24 | E1(i,j) = E(1); 25 | end 26 | end 27 | [x,y,z] = sph2cart(a,e,E1); 28 | c = sqrt(x.^2+y.^2+z.^2); 29 | s = surf(x,y,z,c); 30 | s.EdgeColor = 'none'; 31 | s.FaceColor = 'interp'; 32 | display(s) 33 | end 34 | 35 | function [E] = modulus(CH) 36 | S = inv(CH); 37 | E = zeros(6,1); 38 | E(1) = 1/S(1,1); 39 | E(2) = 1/S(2,2); 40 | E(3) = 1/S(3,3); 41 | E(4) = 1/S(4,4); 42 | E(5) = 1/S(5,5); 43 | E(6) = 1/S(6,6); 44 | end 45 | 46 | function C = generate(CH) 47 | C = zeros(3,3,3,3); 48 | for i = 1:6 49 | for j = 1:6 50 | [a,b] = change(i); 51 | [c,d] = change(j); 52 | C(a,b,c,d) = CH(i,j); 53 | end 54 | end 55 | for i = 1:3 56 | if (i == 3) 57 | j = 1; 58 | else 59 | j = i+1; 60 | end 61 | for m = 1:3 62 | if (m == 3) 63 | n = 1; 64 | else 65 | n = m+1; 66 | end 67 | C(j,i,n,m) = C(i,j,m,n); 68 | C(j,i,m,n) = C(i,j,m,n); 69 | C(i,j,n,m) = C(i,j,m,n); 70 | C(j,i,m,m) = C(i,j,m,m); 71 | C(m,m,j,i) = C(m,m,i,j); 72 | end 73 | end 74 | end 75 | 76 | % change the index 4 5 6 to 23 31 12 77 | function [a,b] = change(w) 78 | 79 | if (w < 4) 80 | a = w; 81 | b = w; 82 | else 83 | if (w == 4) 84 | a = 2; 85 | b = 3; 86 | else 87 | if (w == 5) 88 | a = 3; 89 | b = 1; 90 | else 91 | if (w==6) 92 | a = 1; 93 | b = 2; 94 | end 95 | end 96 | end 97 | end 98 | 99 | end 100 | 101 | function CH = ToMatrix(C) 102 | CH = zeros(6,6); 103 | for i = 1:6 104 | for j = 1:6 105 | [a,b] = change(i); 106 | [c,d] = change(j); 107 | CH(i,j) = C(a,b,c,d); 108 | end 109 | end 110 | end --------------------------------------------------------------------------------