function Modular_Beam_X (load_pt, pre_p, pre_e) %............................................................. % Classic cubic beam for point loads & couples, line load % X COORDINATES CLOSED FORM INTEGRALS %............................................................. % pre_e = # of dummy items before el_type & connectivity % pre_p = # of dummy items before BC_flag % coordinates if ( nargin == 2 ) ; % check for optional data pre_e = 0 ; % no el # in msh_typ_nodes elseif ( nargin == 1 ) ; % check for optional data pre_p = 0 ; pre_e = 0 ; % no pt # in msh_bc_xyz elseif ( nargin == 0 ) ; % check for optional data load_pt = 0 ; pre_p = 0 ; pre_e = 0 ; % no point source data end % if from argument count % ===================================================================== % PHASE 1 % *** SET USER PROBLEM DEPENDENT CONTROLS *** % ===================================================================== % Application and element dependent controls n_g = 2 ; % number of DOF per node (deflection, slope) n_q = 0 ; % number of quadrature points required n_r = 1 ; % number of rows in B_e matrix % ===================================================================== % PHASE 2 % *** BEGIN DATA INPUT AND CHECKING PHASE *** % ===================================================================== % Read mesh input data files [n_m, n_s, P, x, y, z] = get_mesh_nodes (pre_p) ; [n_e, n_n, n_t, el_type, nodes] = get_mesh_elements (pre_e) ; n_d = n_g*n_m ; % system degrees of freedom (DOF) n_i = n_g*n_n ; % number of DOF per element S = zeros (n_d, n_d) ; C = zeros (n_d, 1) ; % initalize sums % Extract EBC flags from packed integer flag P [EBC_flag] = get_ebc_flags (n_g, n_m, P) ; % unpack flags EBC_count = sum( sum ( EBC_flag > 0 ) ) ; % # of EBC fprintf ('Note: expecting %g EBC values. \n', EBC_count) % Read EBC values, if any if ( EBC_count > 0 ) ; % need EBC data [EBC_value] = get_ebc_values (n_g, n_m, EBC_flag) ; % read data end % if any EBC data expected % Read Neumann point loads data, if any, and insert in C if ( load_pt > 0 ) ; % need point loads data [C] = get_and_add_point_sources (n_g, n_m, C); % add point loads end % if any point source expected % Read any material properties for the elements % from optional file msh_properties.tmp load msh_properties.tmp ; % one row per element fprintf ('\n(Echoing file msh_properties.tmp) \n') n_prop = size(msh_properties, 1) ; % == 1 if homogeneous n_vals = size(msh_properties, 2) ; % of application properties % n_prop = number of properties, = n_e or 1 if homogeneous if ( n_prop == 1 ) % then element data are honogeneous fprintf ('%i homogeneous property values \n', n_vals) else fprintf ('%i property values per element \n', n_vals) end % if disp(msh_properties) if ( n_prop > n_e ) error ('ERROR: number of property sets exceeds number of elements') end % if % for beam application only if ( n_prop == 1 ) % then element data are honogeneous E = msh_properties (1, 1) ; % material modulus I = msh_properties (1, 2) ; % section inertia Line_e (1:2) = msh_properties (1, 3:4) ; % trapezoidal line load k_f = msh_properties (1, 5) ; % foundation stiffness Rho = msh_properties (1, 6) ; % mass per unit length % ECHO PROPERTIES echo = 0 ; % turn off/on listing of properties if ( echo ) fprintf (' \n') fprintf ('Homogeneous Element Properties: \n' ) fprintf ('Elastity modulus (N/m^2) = %g \n', E) fprintf ('Moment of inertia (m^4) = %g \n', I) fprintf ('Line Load (N/m) = [ %g %g ] \n', ... Line_e(1), Line_e(2)) fprintf ('Foundation stiffness (N/m^2) = %g \n', k_f) fprintf ('Mass per unit length (Kg/m) = %g \n', Rho) end % if echo end % if homogeneous element properties F_k (1:n_prop) = msh_properties (1:n_prop, 5); % foundation stiffness if ( any ( F_k > 0 )) % BEF pressures will exist BEF = 1 ; fprintf('WARNING: BoEF moment & shear inaccurate for crude meshes \n') else % turn off foundation pressure calculation flag BEF = 0 ; end % if reaction flag % end for beam application only % ====================================================================== % PHASE 3 % ** GENERATE ELEMENT VALUES AND ASSYMBLE INTO SYSTEM ** % ====================================================================== % Assemble n_d by n_d square matrix terms from n_e by n_e for j = 1:n_e ; % loop over elements ====>> ====>> ====>> ====>> ====>> S_e = zeros (n_i, n_i) ; % clear array M_e = zeros (n_i, n_i) ; % clear array NtN = zeros (n_i, n_i) ; % clear array C_p = zeros (n_i, 1) ; C_e = zeros (n_i, 1) ; % clear arrays e_nodes = nodes (j, 1:n_n) ; % connectivity % SET ELEMENT PROPERTIES & GEOMETRY [I, E, Rho, Line_e] = set_constant_beam_prop (n_n); % properties L_e = abs (x(e_nodes(2)) - x(e_nodes(1))) ; % beam length if ( n_prop > 1 ) % each element has some different properties E = msh_properties (j, 1) ; % material modulus I = msh_properties (j, 2) ; % section inertia Line_e (1:2) = msh_properties (j, 3:4) ; % trapezoidal line load k_f = msh_properties (j, 5) ; % foundation stiffness Rho = msh_properties (j, 6) ; % mass per unit length % ECHO PROPERTIES fprintf ('\nProperties for element %g \n', j) fprintf ('Elastity modulus (N/m^2) = %g \n', E) fprintf ('Moment of inertia (m^4) = %g \n', I) fprintf ('Line Load (N/m) = [ %g %g ] \n', ... Line_e(1), Line_e(2)) fprintf ('Foundation stiffness (N/m^2) = %g \n', k_f) fprintf ('Mass per unit length (km/m) = %g \n', Rho) end % if % ELEMENT CONDUCTION AND INTERNAL SOURCE MATRICES % for q = 1:n_q ; % Loop over element quadrature points ----> % Constant cubic element square matrices S_e = (E*I/L_e^3)*[ 12, 6*L_e, -12, 6*L_e ; 6*L_e, 4*L_e^2, -6*L_e, 2*L_e^2 ; -12, -6*L_e, 12, -6*L_e ; 6*L_e, 2*L_e^2, -6*L_e, 4*L_e^2 ] ; % stiffness NtN = [ 156, 22*L_e, 54, -13*L_e ; 22*L_e, 4*L_e^2, 13*L_e, -3*L_e^2 ; 54, 13*L_e, 156, -22*L_e ; -13*L_e, -3*L_e^2, -22*L_e, 4*L_e^2 ]/420; % mass like S_e = S_e + k_f * NtN ; % add foundation stiffness before assembly M_e = (Rho*L_e)*NtN ; % mass matrix % Map line load to node forces & moments; C_p = p_2_F * Line_e if ( any (Line_e) ) ; % then form forcing vector p_2_F = L_e * [ 21, 9 ; 3*L_e, 2*L_e ; 9, 21 ; -2*L_e -3*L_e ] / 60 ; % cubic H, linear Line % 4 x 2 * 2 x 1 = 4 x 1 result C_e = p_2_F (1:n_i, 1:n_n) * Line_e ; % force moment @ nodes end % if or set up resultant node loads for line load % end % for loop over n_q element quadrature points <---- % SCATTER TO (ASSEMBLE INTO) SYSTEM ARRAYS % Insert completed element matrices into system matrices [rows] = get_element_index (n_g, n_n, e_nodes); % eq 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 <<==== <<==== <<==== <<==== <<==== % ======================================================================== % PHASE 4 % APPLY BC AND CONSTRAINTS (Make problem unique) % ======================================================================== % ALLOCATE STORAGE FOR OPTIONAL REACTION RECOVERY if ( EBC_count > 0 ) ; % reactions occur EBC_row = zeros (EBC_count, n_d) ; % reaction data EBC_col = zeros (EBC_count, 1) ; % reaction data [EBC_row, EBC_col] = save_reaction_matrices (EBC_flag, S, C); % EBC_row = row from S for each EBC % EBC_col = row from C for each EBC end % if essential BC exist (almost always true) %b % ECHO PROPERTIES %b fprintf ('Application properties are: \n') fprintf ('Elastity modulus = %g \n', E) fprintf ('Moment of inertia = %g \n', I) fprintf ('Line Load = [ %g %g ] \n', Line_e(1), Line_e(2)) % ENFORCE ESSENTIAL BOUNDARY CONDITIONS save_resultant_load_vectors (n_g, C) [S, C] = enforce_essential_BC (EBC_flag, EBC_value, S, C); % ======================================================================== % PHASE 5 % SOLVE FOR UNIQUE SOLUTION AND ITS REACTIONS % ======================================================================== T = S \ C ; % Compute displacements & rotations list_save_beam_displacements (n_g, n_m, T) ; % save and print % OPTIONAL REACTION RECOVERY & SAVE if ( EBC_count > 0 ) ; % reactions exist ? [EBC_react] = recover_reactions_print_save (n_g, n_d, ... EBC_flag, EBC_row, EBC_col, T); % reaction to EBC end % if EBC exist show = 1 ; if ( show==1) % OPTIONAL GRAPHS (saved as portable network graphics format) fprintf ('Begin deflection plot: \n') beam_C1_L2_defl (1) % deflection pause (4) % display for 4 seconds fprintf ('Begin deflection slope plot: \n') beam_C1_L2_defl (2) % slope pause (2) % display for 2 seconds end % if show % ===================================================================== % PHASE 6 % POST-PROCESS ELEMENTS (el qp values and/or el integral) % ===================================================================== % POST-PROCESS ELEMENT REACTIONS (MEMBER FORCES) % output_beam_element_reactions (n_e, n_g, n_n, n_q, nodes, x, y, T) % 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 of Modular_Beam_X % +++++++++++++ functions in alphabetical order +++++++++++++++++ function beam_C1_L2_defl (i_p) % Copyright 2004, J.E. Akin. All rights reserved. % ------------------------------------------------------ % Matlab graph of i_p-th component value of 1 eigenvector, % at mesh node locations % ------------------------------------------------------ % c_x = x coordinates of nod_per_el line polygon % c_y = y coordinates of nod_per_el line polygon % msh_typ_nodes = connectivity list for elements, nt x nod_per_el % loop = corners for nod_per_el line polygon % nod_per_el = Nodes per element % np = Number of Points % nt = Number of elements % pre_e = Element items before connectivity list pre_e = 0 ; % pre_p = Nodal items before coordinates pre_p = 1; % msh_bc_xyz = Nodal coordinates (with preceeding data) % t_x = x coordinates of nod_per_el corners % t_y = y coordinates of nod_per_el corners clear fid_1 fid_5 if ( nargin == 0 ) i_p = 1 ; end % if % Read coordinate file and connectivity file % integer bc code, real xy pairs for np points (pre_p = 1) load msh_bc_xyz.tmp ; % Set control data: number of points np = size (msh_bc_xyz,1) ; % number of nodal points fprintf ('Read %g mesh coordinate pairs \n', np) ns = size (msh_bc_xyz,2) - pre_p ; % space dimension if ( ns > 1 ) %b error ('This is not a 1D mesh') fprintf ('Not 1D: will use x-coordinate only \n') end % if not 2D data % Set control data: number elements load msh_typ_nodes.tmp ; % nod_per_el nodes per element nt = size (msh_typ_nodes,1) ; % number of elements in mesh nod_per_el = size (msh_typ_nodes,2) - pre_e -1 ; % nodes per elem fprintf ('Read %g elements connections \n', nt) ng = 1 ; % number of generalized dof % ==================== 4 files ==================== file_1 = ['node_results']; filename_1 = [file_1, '.tmp']; fid_1= fopen(filename_1, 'r') ; % load the file array for this result Result_1 = fscanf (fid_1, '%g \n', [inf]) ; NP = size (Result_1, 1) ; if ( NP == 0 ) error ('Error missing file ', file_1, '.tmp') end % if error if ( NP ~= np ) fprintf ('Read %g nodal dof \n', NP) ng = NP / np ; fprintf ('with %g per node \n', ng ) end % if max_p = ng ; if ( i_p > max_p ) error ('i_p > available data') end % if error Result_1 = reshape (Result_1, ng, np) ; Result_1 = Result_1' ; % ==================== end 4 files ==================== H (2) = 0. ; HC1 (4) = 0. ; DHC1 (4) = 0. ; x (np) = 0. ; % pre-allocate array x t_nodes (nod_per_el) = 0 ; % Optional pre-allocation t_x (nod_per_el) = 0 ; % Optional pre-allocation t_y (nod_per_el) = 0 ; % Optional pre-allocation c_x (nod_per_el + 1) = 0 ; % Optional pre-allocation c_y (nod_per_el + 1) = 0 ; % Optional pre-allocation loop (nod_per_el + 1) = 0 ; % Optional pre-allocation % set constants [loop] = get_El_Loop (nod_per_el) ; % msh_bc_xyz has: pre_p items then: x, y x = msh_bc_xyz (1:np, (pre_p+1)) ; % extract x column y_1 = Result_1(:, 1) ; % nodal disp R1x = max(y_1) ; R1n = min(y_1); dy_1 = Result_1(:, 2) ; % nodal slope R2x = max(dy_1) ; R2n = min(dy_1); [norm, at] = max ( abs (y_1) ); if ( norm == 0 ) error ('Null displacement, nothing to plot') end % if %b norm = y_1 (at) ; %b y_1 = y_1 / norm ; %b dy_1 = dy_1 / norm ; if ( i_p == 1 ) y = y_1 ; else y = dy_1 ; end % if % Initialize plots xmax = max (x) ; xmin = min (x) ; y_1X = max (y) ; y_1N = min (y) ; ymax = max (y_1X) ; ymin = min (y_1N) ; ymax = ymax + abs (ymax)/10. ; ymin = ymin - abs (ymin)/10. ; if ( ymin == ymax ) disp(ymin) error('All values are the above constant') end % if %b ymax=1.0 %b ymin=-2 clf % clear graphics %b axis ([xmin, xmax, ymin, ymax]) % set axes hold on % hold image for plots xlabel ('X') % add label % Loop over all elements %b el_min = ymin ; el_max = ymax ; el_min = ymax ; el_max = ymin ; for it = 1:nt ; % Extract element connectivity t_nodes = msh_typ_nodes (it, (pre_e+2):(nod_per_el+pre_e+1)); % Skip point elements, if any if ( all (t_nodes) ) % then valid line % Extract element coordinates & values t_x = x (t_nodes) ; % x at those nodes, only A = abs( t_x(2) - t_x(1)) ; % element length t_y = y_1 (t_nodes) ; % y at those nodes, only t_dy = dy_1 (t_nodes) ; % dy at those nodes, only D (1:2:4) = t_y ; D (2:2:4) = t_dy ; % Loop over local points on the cubic polynomial element n_poly = ceil ( 95 / nt) ; for k = 1: (n_poly + 1) % points in parametric space % get element parametric interpolation functions R = (k - 1)/n_poly ; % on 0 to 1 X = 2*R - 1 ; % on -1 to 1 % H = ELEMENT SHAPE FUNCTIONS % X = LOCAL COORDINATE OF POINT, -1 TO +1 % LOCAL NODE COORD. ARE -1,+1 1------------2 H (1) = 0.5*(1 - X) ; H (2) = 0.5*(1 + X) ; x_el (k) = H * t_x ; % true X value HC1(1) = (2 - 3*X + X^3)/4; HC1(2) = (1 - X - X^2 + X^3)*A/8; HC1(3) = (2 + 3*X - X^3)/4; HC1(4) = (-1 - X + X^2 + X^3)*A/8; y_el (k) = HC1 * D' ; % tXue y value DHC1(1) = (-3 + 3*X*X) * 0.5 / A; DHC1(2) = (-1 - 2*X + 3*X*X) * 0.25 ; DHC1(3) = ( 3 - 3*X*X) * 0.5d0 / A; DHC1(4) = (-1 + 2*X + 3*X*X) * 0.25; dy_el (k) = DHC1 * D' ; % true y value end % for k format short plot (x, y, 'ko') % nodal value symbols if ( i_p == 1 ) plot (x_el, y_el) % interpolated values max_el = max (y_el) ; min_el = min (y_el) ; elseif ( i_p == 2 ) plot (x_el, dy_el) % interpolated values max_el = max (dy_el) ; min_el = min (dy_el) ; end % if if ( max_el > el_max ) el_max = max_el ; end % if if ( min_el < el_min ) el_min = min_el ; end % if end % if has non-zero nodes end % for all elements %b if ( el_max > ymax ) fprintf ('Max interior value was %g \n', el_max) ymax = el_max ; %b end % if %b if ( el_min < ymin ) ymin = el_min ; fprintf ('Min interior value was %g \n', el_min) %b end % if axis ([xmin, xmax, ymin, ymax]) % set axes if ( i_p == 1 ) ylabel (['Beam Displacement (nodal max = ', ... num2str(R1x), ', min = ', num2str(R1n), ')']) title(['Displacement: ', int2str(nt),' Elements, ', ... int2str(np), ' Nodes, (', int2str(nod_per_el), ... ' per Element)']) elseif ( i_p == 2 ) ylabel (['Beam Slope (nodal max = ', ... num2str(R2x), ', min = ', num2str(R2n), ')']) title(['Slope: ', int2str(nt),' Elements, ', ... int2str(np), ' Nodes, (', int2str(nod_per_el), ... ' per Element)']) end % if grid % Create plot copies for report use if ( i_p == 1 ) print ('-dpng', ['Beam_deflections']) v_text = ['Created Beam_deflections.png'] ; elseif ( i_p == 2 ) print ('-dpng', ['Beam_slope']) v_text = ['Created Beam_slope.png'] ; end % if fprintf (1,'%s', v_text) ; fprintf (1, ' \n' ) hold off % end of beam_C1_L2_defl function [S, C] = enforce_essential_BC (EBC_flag, EBC_value, S, C) % modify system linear eqs for essential boundary conditions % (by trick to avoid matrix partitions, loses reaction data) n_d = size (C, 1) ; % number of DOF eqs if ( size (EBC_flag, 2) > 1 ) ; % change to vector copy flag_EBC = reshape ( EBC_flag', 1, n_d) ; value_EBC = reshape ( EBC_value', 1, n_d) ; else flag_EBC = EBC_flag ; value_EBC = EBC_value ; end % if for j = 1:n_d % check all DOF for essential BC if ( flag_EBC (j) ) % then EBC here % Carry known columns*EBC to RHS. Zero that column and row. % Insert EBC identity, 1*EBC_dof = EBC_value. EBC = value_EBC (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 % end enforce_essential_BC (EBC_flag, EBC_value, S, C) function [C] = get_and_add_point_sources (n_g, n_m, C) load msh_load_pt.tmp ; % node, DOF, value (eq. number) n_u = size(msh_load_pt, 1) ; % number of point sources if ( n_u < 1 ) ; % missing data error ('No load_pt data in msh_load_pt.tmp') end % if user error fprintf ('Read %g point sources. \n', n_u) fprintf ('Node DOF Source_value \n') for j = 1:n_u ; % non-zero Neumann pts node = msh_load_pt (j, 1) ; % global node number DOF = msh_load_pt (j, 2) ; % local DOF number value = msh_load_pt (j, 3) ; % point source value fprintf ('%g %g %g \n', node, DOF, value) Eq = n_g * (node - 1) + DOF ; % row in system matrix C (Eq) = C (Eq) + value ; % add to system column matrix end % for each EBC fprintf ('\n') % end get_and_add_point_sources (n_g, n_m, C) function [EBC_flag] = get_ebc_flags (n_g, n_m, P) EBC_flag = zeros(n_m, n_g) ; % initialize for k = 1:n_m ; % loop over all nodes if ( P(k) > 0 ) ; % at least one EBC here [flags] = unpack_pt_flags (n_g, k, P(k)) ; % unpacking EBC_flag (k, 1:n_g) = flags (1:n_g) ; % populate array end % if EBC at node k end % for loop over all nodes % end get_ebc_flags function [EBC_value] = get_ebc_values (n_g, n_m, EBC_flag) EBC_value = zeros(n_m, n_g) ; % initialize to zero load msh_ebc.tmp ; % node, DOF, value (eq. number) n_c = size(msh_ebc, 1) ; % number of constraints fprintf ('Read %g EBC data with Node, DOF, Value. \n', n_c) disp(msh_ebc) ; % echo input for j = 1:n_c ; % loop over ebc inputs node = round (msh_ebc (j, 1)) ; % node in mesh DOF = round (msh_ebc (j, 2)) ; % DOF # at node value = msh_ebc (j, 3) ; % EBC value % Eq = n_g * (node - 1) + DOF ; % row in system matrix EBC_value (node, DOF) = value ; % insert value in array if ( EBC_flag (node, DOF) == 0 ) % check data consistency fprintf ('WARNING: EBC but no flag at node %g & DOF %g. \n', ... node, DOF) % EBC_flag (node, DOF) = 1; % try to recover from data error end % if common user error end % for each EBC EBC_count = sum (sum ( EBC_flag > 0 )) ; % check input data if ( EBC_count ~= n_c ) ; % probable user error fprintf ('WARNING: mismatch in bc_flag count & msh_ebc.tmp') end % if user error % end get_ebc_values function [rows] = get_element_index (n_g, n_n, e_nodes) % calculate system DOF numbers of element, for gather, scatter rows = zeros (1, n_g*n_n) ; % allow for node = 0 for k = 1:n_n ; % loop over element nodes global_node = round (e_nodes (k)) ; % corresponding sys node for i = 1:n_g ; % loop over DOF at node eq_global = i + n_g * (global_node - 1) ; % sys DOF, if any eq_element = i + n_g * (k - 1) ; % el DOF number if ( eq_global > 0 ) ; % check node=0 trick rows (1, eq_element) = eq_global ; % valid DOF > 0 end % if allow for omitted nodes end % for DOF i % end local DOF loop end % for each element node % end local node loop % end get_element_index function [n_e, n_n, n_t, el_type, nodes] = get_mesh_elements (pre_e) ; % MODEL input file controls (for various data generators) if (nargin == 0) ; % default to no proceeding items in data pre_e = 0 ; % Dummy items before el_type & connectivity end % if 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 n_n = size (msh_typ_nodes,2) - pre_e - 1 ; % nodes per element fprintf ('Read %g elements with type number & %g nodes each. \n', ... n_e, n_n) el_type = round (msh_typ_nodes(:, pre_e+1)); % el type number >= 1 n_t = max(el_type) ; % number of element types fprintf ('Maximum number of element types = %g. \n', n_t) nodes (1:n_e, 1:n_n) = msh_typ_nodes (1:n_e, (pre_e+2:pre_e+1+n_n)); disp(msh_typ_nodes (:, (pre_e+1:pre_e+1+n_n))) % echo data % end get_mesh_elements function [n_m, n_s, P, x, y, z] = get_mesh_nodes (pre_p) ; % MODEL input file controls (for various data generators) if (nargin == 0) % override default pre_p = 0 ; % Dummy items before BC_flag % coordinates end % if % READ MESH AND EBC_FLAG INPUT DATA % specific problem data from MODEL data files (sequential) load msh_bc_xyz.tmp ; % bc_flag, x-, y-, z-coords n_m = size (msh_bc_xyz,1) ; % number of nodal points in mesh if ( n_m == 0 ) ; % data missing ! error ('Error missing file msh_bc_xyz.tmp') end % if error n_s = size (msh_bc_xyz,2) - pre_p - 1 ; % number of space dimensions fprintf ('Read %g nodes with bc_flag & %g coordinates. \n', n_m, n_s) msh_bc_xyz (:, (pre_p+1))= round (msh_bc_xyz (:, (pre_p+1))); P = msh_bc_xyz (1:n_m, (pre_p+1)) ; % integer Packed BC flag x = msh_bc_xyz (1:n_m, (pre_p+2)) ; % extract x column y (1:n_m, 1) = 0.0 ; z (1:n_m, 1) = 0.0 ; % default to zero if (n_s > 1 ) ; % check 2D or 3D y = msh_bc_xyz (1:n_m, (pre_p+3)) ; % extract y column end % if 2D or 3D if ( n_s == 3 ) ; % check 3D z = msh_bc_xyz (1:n_m, (pre_p+4)) ; % extract z column end % if 3D disp(msh_bc_xyz (:, (pre_p+1):(pre_p+1+n_s))) ; % echo data % end get_mesh_nodes function list_save_beam_displacements (n_g, n_m, T) fprintf ('\n') ; fprintf('Node Y_displacement Z_rotation at %g nodes \n', n_m) T_matrix = reshape (T, n_g, n_m)' ; % pretty shape % save results (displacements) to MODEL file: node_results.tmp fid = fopen('node_results.tmp', 'w') ; % open for writing for j = 1:n_m ; % node loop, save displ fprintf (fid, '%g %g \n', T_matrix (j, 1:n_g)) ; % to file fprintf ('%g %g %g \n', j, T_matrix (j, 1:n_g)) ; % to screen end % for j DOF % end list_save_beam_displacements (n_g, n_m, T) function list_save_displacements_results (n_g, n_m, T) fprintf ('\n') ; fprintf('X_disp Y_disp Z_disp at %g nodes \n', n_m) T_matrix = reshape (T, n_g, n_m)' ; % pretty shape disp (T_matrix) ; % print displacements % save results (displacements) to MODEL file: node_results.tmp fid = fopen('node_results.tmp', 'w') ; % open for writing for j = 1:n_m ; % save displacements if ( n_g == 1 ) fprintf (fid, '%g \n', T_matrix (j, 1:n_g)) ; elseif ( n_g == 2 ) fprintf (fid, '%g %g \n', T_matrix (j, 1:n_g)) ; elseif ( n_g == 3 ) fprintf (fid, '%g %g %g \n', T_matrix (j, 1:n_g)) ; elseif ( n_g == 4 ) fprintf (fid, '%g %g %g %g \n', T_matrix (j, 1:n_g)) ; elseif ( n_g == 5 ) fprintf (fid, '%g %g %g %g %g \n', T_matrix (j, 1:n_g)) ; elseif ( n_g == 6 ) fprintf (fid, '%g %g %g %g %g %g \n', T_matrix (j, 1:n_g)) ; else error ('reformat list_save_displacements_results for n_g > 6.') end % if end % for j DOF % end list_save_displacements_results (T) function list_save_temperature_results (T) n_m = size (T, 1) ; % get size fprintf('Temperature at %g nodes \n', n_m) ; % header % save results (temperature) to MODEL file: node_results.tmp fid = fopen('node_results.tmp', 'w') ; % open for writing for j = 1:n_m ; % save temperature fprintf ( fid, '%g \n', T (j)) ; % print fprintf (' %g %g \n', j, T (j)) ; % sequential save end % for j DOF % end list_save_temperature_results (T) function output_PlaneStress_stresses(n_e, n_g, n_n, n_q, nodes, x,y,T) % POST-PROCESS ELEMENT STRESS RECOVERY & SAVE fid = fopen('el_qp_xyz_fluxes.tmp', 'w') ; % open for writing fprintf ('\n') ; % blank line fprintf('Elem, QP, X_qp, Y_qp \n') ;% header fprintf('Elem, QP, Stress_qp: xx yy xy \n');% header for j = 1:n_e ; % loop over elements ====>> e_nodes = nodes (j, 1:n_n) ; % connectivity [a, b, c, center, two_A] = form_T3_geom_constants (x, y, e_nodes); [t_e, Body_e, E_e] = set_constant_plane_stress_prop; % properties % get DOF numbers for this element, gather solution [rows] = get_element_index (n_g, n_n, e_nodes) ; % eq numbers T_e = T (rows) ; % gather element DOF for q = 1:n_q ; % Loop over element quadrature points ----> % H_i (x,y) = (a_i + b_i*x + c_i*y)/two_A % interpolations B_e (1, 1:2:5) = b (1:3)/two_A ; B_e (2, 2:2:6) = c (1:3)/two_A ; B_e (3, 1:2:5) = c (1:3)/two_A ; B_e (3, 2:2:6) = b (1:3)/two_A ; % COMPUTE GRADIENT & HEAT FLUX, SAVE LOCATION AND VALUES Strains = B_e * T_e ; % mechanical strain Stress = E_e * Strains ; % mechanical stress fprintf (fid,'%g %g %g %g %g \n', center(1), center(2), ... Stress(1), Stress(2), Stress(3));% save fprintf ('%g %g %g %g \n', j, q, center(1:2));% prt fprintf ('%g %g %g %g %g \n', j, q, Stress(1:3));% prt fprintf ('\n') ;% prt end % for loop over n_q element quadrature points <---- end % for each j element in mesh % end output_PlaneStress_stresses (n_e, n_g, n_n, n_q, nodes, x, y, T) function output_T3_heat_flux (n_e, n_g, n_n, n_q, nodes, x, y, T) % POST-PROCESS ELEMENT HEAT FLUX RECOVERY & SAVE fid = fopen('el_qp_xyz_fluxes.tmp', 'w') ; % open for writing fprintf ('\n') ; % blank line fprintf('Elem, X_qp, Y_qp, HeatFlux_x, HeatFlux_y \n');% header for j = 1:n_e ; % loop over elements ====>> e_nodes = nodes (j, 1:n_n) ; % connectivity [a, b, c, center, two_A] = form_T3_geom_constants (x, y, e_nodes); [t_e, Body_e, E_e] = set_constant_plane_stress_prop; % properties % get DOF numbers for this element, gather solution [rows] = get_element_index (n_g, n_n, e_nodes) ; % eq numbers T_e = T (rows) ; % gather element DOF for q = 1:n_q ; % Loop over element quadrature points ----> % H_i (x,y) = (a_i + b_i*x + c_i*y)/two_A % interpolations B_e (1, 1:3) = b(1:3) / two_A ; % dH/dx B_e (2, 1:3) = c(1:3) / two_A ; % dH/dy % COMPUTE GRADIENT & HEAT FLUX, SAVE LOCATION AND VALUES Gradient = B_e * T_e ; % gradient vector HeatFlux = E_e * Gradient ; % heat flux vector fprintf (fid, '%g %g %g %g \n', center(1:2), HeatFlux(1:2));% save fprintf ('%g %g %g %g %g \n', j, center(1:2), HeatFlux(1:2));% prt end % for loop over n_q element quadrature points <---- end % for each j element in mesh <<==== % end output_T3_heat_flux (n_e, n_g, n_n, n_q, nodes, x, y, T) function [EBC_react] = recover_reactions_print_save (n_g, n_d, ... EBC_flag, EBC_row, EBC_col, T) % get EBC reaction values by using rows of S & C (before EBC) n_d = size (T, 1) ; % number of system DOF % n_c x 1 = n_c x n_d * n_d x 1 + n_c x 1 EBC_react = EBC_row * T - EBC_col ; % matrix reactions (+-) % save reactions (forces) to MODEL file: node_reaction.tmp fprintf ('\n') ; % Skip a line fprintf ('Node, DOF, Value for %g Reactions \n', ... sum (sum (EBC_flag > 0))) ; % header fid = fopen('node_reaction.tmp', 'w') ; % open for writing if ( size (EBC_flag, 2) > 1 ) ; % change to vector copy flag_EBC = reshape ( EBC_flag', 1, n_d) ; % changed else flag_EBC = EBC_flag ; % original vector end % if Totals = zeros (1, n_g) ; % zero input totals kount = 0 ; % initialize counter for j = 1:n_d ; % extract all EBC reactions if ( flag_EBC(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 \n', node, j_g, React);% save fprintf ('%g %g %g \n', node, j_g, React); % print Totals (j_g) = Totals (j_g) + React ; % sum all components end % if EBC for this DOF end % for over all j-th DOF fprintf ('Totals = ') ; disp(Totals) ; % echo totals % end recover_reactions_print_save (EBC_row, EBC_col, T) function [EBC_row, EBC_col] = save_reaction_matrices (EBC_flag, S, C) n_d = size (C, 1) ; % number of system DOF EBC_count = sum (sum (EBC_flag)) ; % count EBC & reactions EBC_row = zeros(EBC_count, n_d) ; % reaction data EBC_col = zeros(EBC_count, 1) ; % reaction data if ( size (EBC_flag, 2) > 1 ) ; % change to vector copy flag_EBC = reshape ( EBC_flag', 1, n_d) ; % changed else flag_EBC = EBC_flag ; % original vector end % if kount = 0 ; % initialize counter for j = 1:n_d % System DOF loop, check for displacement BC if ( flag_EBC (j) ) ; % then EBC here % 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, 1) = C (j) ; % copy reaction data end % if EBC for this DOF end % for over all j-th DOF % end sys DOF loop % end save_reaction_matrices (S, C, EBC_flag) function save_resultant_load_vectors (n_g, C) % save resultant forces to MODEL file: node_resultants.tmp n_d = size (C, 1) ; % number of system DOF fprintf ('\n') ; % Skip a line % fprintf ('Node, DOF, Resultant Force (1) or Moment (2) \n') fprintf ('Node, DOF, Resultant input sources \n') fid = fopen('node_resultant.tmp', 'w'); % open for writing Totals = zeros (1, n_g) ; % zero input totals for j = 1:n_d ; % extract all resultants if ( C (j) ~= 0. ) ; % then source here % Output node_number, component_number, value, equation_number node = ceil(j/n_g) ; % node at DOF j j_g = j - (node - 1)*n_g ; % 1 <= j_g <= n_g value = C (j) ; % resultant value fprintf ( fid, '%g %g %g %g \n', node, j_g, value, j);% save fprintf ('%g %g %g \n', node, j_g, value); % print Totals (j_g) = Totals (j_g) + value ; % sum all inputs end % if non-zero for this DOF end % for over all j-th DOF fprintf ('Totals = ') ; disp(Totals) ; % echo totals % end save_resultant_load_vectors (n_g, n_m, C) function [I, E, Rho, Line_e] = set_constant_beam_prop (n_n, Option) ; if ( nargin == 1 ) Option = 1 ; elseif ( nargin == 0 ) n_n = 2 ; Option = 1 ; end % if problem Option number Line_e = zeros (n_n, 1) ; % default line load at nodes switch Option case 1 % Propped cantilever with uniform load, L, L/4 % Wall reactions: V=37*Line*L/64 M=7*Line*L^2/64 % Roller reaction: R= 43*Line*L/64 % Total vertical load: 5*Line*L/4 % *-----(1)-----*-----(2)-----*--(3)--* EI % Fixed@1 L/2 2 Roller@3 L/4 4 I = 1.0 ; E = 1.0 ; Rho = 0.0 ; Line_e = [1.0; 1.0] ; case 2 % cantilever with uniform load, L I = 1.0 ; E = 1.0 ; Rho = 0.0 ; Line_e = [1.0; 1.0] ; otherwise I = 1.0 ; E = 1.0 ; Rho = 0.0; % default shape & material end % switch % end set_constant_beam_prop; function [t_e, Body_e, E_e] = set_constant_plane_stress_prop ; t_e = 1 ; Body_e (1:2) = 0. ; % defaults % case 1 t_e = 5e-3 ; % thickness Body_e (1:2) = [5e5, 0.] ; % components E = 15e9 ; % Elastic modulus nu = 0.25 ; % Poisson's ratio % plane stress E_v = E/(1 - nu^2) ; % constant 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 %end set_constant_plane_stress_prop function [t_e, Q_e, E_e] = set_constant_2D_conduction_prop % Manually set constant element properties (Fig 11.9 text) Q_e = 0. ; t_e = 1. ; % defaults % case 1 Kx = 8. ; Ky = 8. ; Kxy = 0. ; % thermal conductivity % case 2 kx = 1. ; Ky = 1. ; Kxy = 0. ; % insert E_e = zeros (2, 2) ; % constitutive matrix E_e (1, 1) = Kx ; E_e (1, 2) = Kxy ; % non-zero term E_e (2, 1) = Kxy ; E_e (2, 2) = Ky ; % non-zero term % end set_constant_2D_conduction_prop function [flags] = unpack_pt_flags (n_g, N, flag) % unpack n_g integer flags from the n_g digit flag at node N % integer flag contains (left to right) f_1 f_2 ... f_n_g full = flag ; % copy integer check = 0 ; % validate input for Left2Right = 1:n_g ; % loop over local DOF at k Right2Left = n_g + 1 - Left2Right ; % reverse direction work = floor (full / 10) ; % work item keep = full - work * 10 ; % work item flags (Right2Left) = keep ; % insert into array full = work ; % work item check = check + keep * 10^(Left2Right - 1) ; % validate end % for each local DOF if ( flag > check ) ; % check for likely error fprintf ('WARNING: bc flag likely reversed at node %g. \n', N) end % if likely user error % end unpack_pt_flags %=================== Running =========================================== % >> Modular_Beam_X % propped cantilever % Read 4 nodes with bc_flag & 1 coordinates. % 11 0 % 0 2 % 10 4 % 0 5 % % Read 3 elements with type number & 2 nodes each. % Maximum number of element types = 1. % 1 1 2 % 1 2 3 % 1 3 4 % % Note: expecting 3 EBC values. % Read 3 EBC data with Node, DOF, Value. % 1 1 0 % 1 2 0 % 3 1 0 % % Application properties are: % Elastity modulus = 1 % Moment of inertia = 1 % Line Load = [ 1 1 ] % % Node, DOF, Resultant Force (1) or Moment (2) % 1 1 1 % 1 2 0.333333 % 2 1 2 % 3 1 1.5 % 3 2 -0.25 % 4 1 0.5 % 4 2 -0.0833333 % Totals = 5.0000 0.0000 % % Node Y_displacement Z_rotation at 4 nodes % 1 0 0 % 2 1.08333 0.208333 % 3 0 -0.833333 % 4 -0.708333 -0.666667 % % Node, DOF, Value for 3 Reactions % 1 1 -2.3125 % 1 2 -1.75 % 3 1 -2.6875 % Totals = -5.0000 -1.7500 % % >> addpath /net/course-a/mech517/public_html/Matlab_Plots % % >> mesh_shrink_plot % Read 4 mesh coordinate pairs, 3 elements with 2 nodes each % % >> bc_flags_plot % % >> beam_C1_L2_defl % Read 8 nodal dof, with 2 per node % % >> beam_C1_L2_defl(2) % % >> quiver_reaction_vec_mesh(1) % % >> quiver_reaction_vec_mesh(2) % >> quit