function Plane_Stress_T3_RS %.................................................................. % Plane stress displacements for constant strain triangle, T3 % ISOPARAMETRIC VERSION %.................................................................. % Set given constants n_g = 2 ; % number of DOF per node n_n = 3 ; % number of nodes per element n_i = n_n*n_g ; % number of DOF per element % MODEL input file controls (for various data generators) pre_e = 0 ; % Dummy items before el_type & connectivity pre_p = 0 ; % Dummy items before BC_flag % coordinates % READ MESH AND EBC INPUT DATA % specific problem data from MODEL data files (sequential) load msh_bc_xyz.tmp ; % bc_flag, x_coord, y_coord n_m = size (msh_bc_xyz,1) ; % number of nodal points in mesh n_d = n_g*n_m ; % system degrees of freedom (DOF) if ( n_m == 0 ) ; % data missing ! error ('Error missing file msh_bc_xyz.tmp') end % if error fprintf ('Read %g mesh coordinate pairs \n', n_m) P = msh_bc_xyz (1:n_m, (pre_p+1)) ; % extract integer Packed BC flag x = msh_bc_xyz (1:n_m, (pre_p+2)) ; % extract x column y = msh_bc_xyz (1:n_m, (pre_p+3)) ; % extract y column load msh_typ_nodes.tmp ; % el_type, connectivity list (3) n_e = size (msh_typ_nodes,1) ; % number of elements if ( n_e == 0 ) ; % data file missing error ('Error missing file msh_typ_nodes.tmp') end % if error nod_per_el = size (msh_typ_nodes,2) - pre_e - 1 ; % data checking fprintf ('Read %g elements with %g nodes each \n', n_e, nod_per_el) if ( nod_per_el ~= n_n ) error ('Mesh requires 3 nodes per element') end % if el_type = msh_typ_nodes(:, pre_e+1) ; % element type number >= 1 n_t = max(el_type) ; % number of element types % BOOKKEEPING FOR BC FLAGS AND VALUES % Allocate for BC flags and values EBC_flag = zeros(n_m, n_g) ; NBC_flag = zeros(n_m, n_g) ; EBC_value = zeros(n_m, n_g) ; NBC_value = zeros(n_m, n_g) ; % Extract EBC flags from packed integer flag P (for n_g=2 only) for j = 1:n_m % loop over each node, unpack 2 digit flag Boolean = floor(P(j)/10) ; % extract first digit EBC_flag (j, 1) = Boolean ; % insert first flag EBC_flag (j, 2) = P (j) - Boolean * 10 ; % extract 2-nd digit end % for node j in the mesh % Reorder and count BC flags and values EBC_flag = reshape (EBC_flag', n_d, 1) ; % change to vector NBC_flag = reshape (NBC_flag', n_d, 1) ; % change to vector EBC_value = reshape (EBC_value', n_d, 1) ; % change to vector NBC_value = reshape (NBC_value', n_d, 1) ; % change to vector % Optional storage allocation for reaction recovery EBC_count = sum(EBC_flag) ; % number of EBC's NBC_count = sum(NBC_flag) ; % number of NBC's EBC_row = zeros(EBC_count, n_d) ; EBC_col = zeros(EBC_count, 1) ; EBC_react = zeros(EBC_count, 1) ; % reaction allocation % SET ELEMENT PROPERTIES and body force % Manually set constant element properties t = 5e-3 ; % default thickness E = 15e9 ; % Elastic modulus nu = 0.25 ; % Poisson's ratio E_v = E/(1 - nu^2) ; % constant E_e = zeros (3, 3) ; % constitutive matrix E_e (1, 1) = E_v ; E_e (1, 2) = E_v * nu ; % non-zero term E_e (2, 1) = E_v * nu ; E_e (2, 2) = E_v ; % non-zero term E_e (3, 3) = E_v * (1 - nu) / 2 ; % non-zero term has_body_force = 1 ; % body forces on body_force (1:2) = [ 5e5, 0. ] ; % components % Tabulate quadrature data for unit triangle n_q = 1 ; % exact for linear polynomials r_q (1) = 1./3 ; s_q (1) = 1./3 ; w_q (1)= 1./2 ; % tabulated % GENERATE ELEMENT MATRICES AND ASSYMBLE INTO SYSTEM % Assemble n_d by n_d square matrix terms S = zeros (n_d, n_d) ; C = zeros (n_d, 1) ; % initalize sums % Generate element arrays for j = 1:n_e ; % element loop ===>> thick = t * el_type (j) ; % integer multiple e_nodes = msh_typ_nodes (j, (pre_e+2):(pre_e+4)); % connectivity % Define nodal coordinates xy_e (1:n_n, 1) = x(e_nodes) ; % x coord at el nodes xy_e (1:n_n, 2) = y(e_nodes) ; % y coord at el nodes % Numerical Intergation of S_e, C_e S_e = zeros (n_i, n_i) ; C_e = zeros (n_i, 1) ; % initalize values E_q = zeros (n_i, n_i) ; B_q = zeros (3, n_i) ; % initalize values for q = 1:n_q ; % begin loop ---> r = r_q (q) ; s = s_q (q) ; w = w_q (q) ; % recover data H_q = [(1-r-s), r, s] ; % interpolations b_q = [ -1 , 1, 0 ; ... % dH/dr -1 , 0, 1 ] ; % dH/ds % Global position and Jacobian xy_q = H_q * xy_e ; % 1 x 2 % global (x, y) Jacobian = b_q * xy_e ; % 2 x 2 % d(x,y)/d(r,s) J_det = abs( det (Jacobian)) ; % 1 x 1 % determinant J_Inv = inv (Jacobian) ; % 2 x 2 % inverse % global derivatives of H d_q = J_Inv * b_q ; % 2 x 3 % dH/dx & dH/dy E_q = E_e ; % 3 x 3 % properties t_q = thick ; % 1 x 1 % thickness % define 3 by 6 strain-displacement matrix, B_q B_q(1,1:6)=[d_q(1,1), 0.0 , d_q(1,2), 0.0 , d_q(1,3), 0.0 ]; B_q(2,1:6)=[0.0 , d_q(2,1), 0.0 , d_q(2,2), 0.0, d_q(2,3)]; B_q(3,1:6)=[d_q(2,1), d_q(1,1), d_q(2,2), d_q(1,2), d_q(2,3), d_q(1,3)]; % ELEMENT MATRICES UPDATES S_e = S_e + (B_q' * E_q * B_q) * t_q * J_det * w_q (q) ; % stiff % body force resultants point_x = H_q * body_force(1)*t_q * J_det * w_q(q); % x resultant point_y = H_q * body_force(2)*t_q * J_det * w_q(q); % y resultant C_e(1:2:5) = C_e(1:2:5) + point_x' ; % odd rows x C_e(2:2:6) = C_e(2:2:6) + point_y' ; % even rows y end % for q-th quadrature point (el matrices complete) <----- % SCATTER TO SYSTEM ARRAYS % Insert completed element matrices into system matrices rows (1:2:5) = n_g*(e_nodes(1:3) - 1) + 1 ; % element DOF numbers rows (2:2:6) = n_g*(e_nodes(1:3) - 1) + 2 ; % element DOF numbers S (rows, rows) = S (rows, rows) + S_e ; % add to system sq C (rows) = C (rows) + C_e ; % add to sys column end % for each j element in mesh <<==== % INSERT EBC AND NBC (if any) kount = 0 ; % initialize counter for j = 1:n_d ; % DOF loop ====>> if ( NBC_flag(j) ) ; % then NBC here C (j) = C (j) + NBC_value (j) ; % add force value end % if NBC for this DOF % ENFORCE ESSENTIAL BOUNDARY CONDITIONS if ( EBC_flag(j) ) % then EBC here if ( EBC_flag(j) == NBC_flag(j) ) % warning both here fprintf ('Usually an error: EBC and NBC at same DOF \n') end % if fatal BC data % Save reaction data to be destroyed by EBC solver trick kount = kount + 1 ; % copy counter EBC_row(kount, 1:n_d) = S (j, 1:n_d) ; % copy reaction data EBC_col(kount) = C (j) ; % copy reaction data % Insert EBC identity to avoid matrix partition accounting EBC = EBC_value(j) ; % recover EBC value C (:) = C (:) - EBC * S (:, j) ; % carry known column to RHS S (:, j) = 0 ; S (j, :) = 0 ; % clear, restore symmetry S (j, j) = 1 ; C (j) = EBC ; % insert identity into row end % if EBC for this DOF end % for over all j-th DOF <<==== % DISPLACEMENT SOLUTION & SAVE T = S \ C ; % Compute unknown displacements fprintf ('\n') ; fprintf('X_disp Y_disp at %g nodes \n', n_m) disp (reshape(T, n_g, n_m)') % save results (displacements) to MODEL file: node_results.tmp fid = fopen('node_results.tmp', 'w') ; % open for writing for j = 1:n_g:n_d ; % save displacements fprintf ( fid, '%g %g \n', T (j), T (j+1) ) ; % n_g=2 only ! end % for j DOF % REACTION RECOVERY & SAVE EBC_react = EBC_row * T - EBC_col ; % Reaction from matrix (+-) % save reactions (forces) to MODEL file: node_reaction.tmp fprintf ('Node, Component, Value, Eq. for %g Reactions \n', EBC_count) ; fid = fopen('node_reaction.tmp', 'w') ; % open for writing kount = 0 ; % initialize counter for j = 1:n_d ; % extract all EBC reactions if ( EBC_flag(j) ) % then EBC here % Output node_number, component_number, value, equation_number kount = kount + 1 ; % copy counter node = ceil(j/n_g) ; % node at DOF j j_g = j - (node - 1)*n_g ; % 1 <= j_g <= n_g React = EBC_react (kount, 1) ; % reaction value fprintf ( fid, '%g %g %g %g \n', node, j_g, React, j) ; fprintf ('%g %g %g %g \n', node, j_g, React, j) ; end % if EBC for this DOF end % for over all j-th DOF % STRESS RECOVERY & SAVE fid = fopen('el_qp_xyz_fluxes.tmp', 'w') ; % open for writing fprintf ('\n') ; fprintf('Elem, X_qp, Y_qp, Sig_x, Sig_y, Sig_xy \n') for j = 1:n_e ; % element loop ===>> thick = t * el_type (j) ; % integer multiple e_nodes = msh_typ_nodes (j, (pre_e+2):(pre_e+4)); % connectivity % Define nodal coordinates xy_e (1:n_n, 1) = x(e_nodes) ; % x coord at el nodes xy_e (1:n_n, 2) = y(e_nodes) ; % y coord at el nodes for q = 1:n_q ; % begin loop ---> r = r_q (q) ; s = s_q (q) ; w = w_q (q) ; % recover data H_q = [(1-r-s), r, s] ; % interpolations b_q = [ -1 , 1, 0 ; ... % dH/dr -1 , 0, 1 ] ; % dH/ds % Global position and Jacobian xy_q = H_q * xy_e ; % 1 x 2 % global (x, y) Jacobian = b_q * xy_e ; % 2 x 2 % d(x,y)/d(r,s) J_Inv = inv (Jacobian) ; % 2 x 2 % inverse % global derivatives of H d_q = J_Inv * b_q ; % 2 x 3 % dH/dx & dH/dy E_q = E_e ; % 3 x 3 % properties % define 3 by 6 strain-displacement matrix, B_q B_q(1,1:6)=[d_q(1,1), 0.0 , d_q(1,2), 0.0 , d_q(1,3), 0.0 ]; B_q(2,1:6)=[0.0 , d_q(2,1), 0.0 , d_q(2,2), 0.0, d_q(2,3)]; B_q(3,1:6)=[d_q(2,1), d_q(1,1), d_q(2,2), d_q(1,2), d_q(2,3), d_q(1,3)]; % get DOF numbers for this element, gather solution rows (1:2:5) = n_g*(e_nodes(1:3) - 1) + 1 ; % element DOF numbers rows (2:2:6) = n_g*(e_nodes(1:3) - 1) + 2 ; % element DOF numbers T_e = T (rows) ; % 6 x 1 % gather element DOF % COMPUTE STRESSES, SAVE LOCATION AND VALUES Strain = B_q * T_e ; % 3 x 1 % matrix product Stress = E_q * Strain ; % 3 x 1 % matrix product fprintf (fid, '%g %g %g %g %g \n', xy_q(1:2), Stress(1:3)) ; fprintf ('%g %g %g %g %g %g \n', j, xy_q(1:2), Stress(1:3)) ; end % numerical integration loop over q points <---- end % loop for each j element in mesh <<==== % End finite element calculations. % See /home/mech517/public_html/Matlab_Plots for graphic options % http://www.owlnet.rice.edu/~mech517/help_plot.html for help % end Plane_Stress_T3_RS