CrossSolver class
This classe is a Solver of Cross Process of continuous beams. Euler-Bernoulli flexural behavior is assumed (Navier beam theory).
This file contains an implementation of the Cross Process for continuous beams with uniformly distributed loads in each spam.
This is an iterative method that in each step the unbalanced moment of a node is distributed among the two adjacent member sections. In addition, due to this node moment balancing, carry-over portions of the balancing moments are transmitted to the opposite ends of the adjacent members.
For more details of this process, refer to the book "Análise de Estruturas: Conceitos e Métodos Básicos", Third Edition, by Luiz Fernando Martha, Editora LTC - Grupo GEN, 2022.
Contents
Associated classes
The following OOP classes are associated:
- CrossMember class.
- CrossNode class.
- CrossStep class.
Author
Luiz Fernando Martha
History
@version 1.00
Initial version (1.00): August 2022
Initially prepared for the course CIV 2801 - Fundamentos de Computação Gráfica, 2022, second term, Department of Civil Engineering, PUC-Rio.
Class definition
classdef CrossSolver < handle
See documentation on handle super-class.
Public attributes
properties (SetAccess = public, GetAccess = public) nmemb = 0; % number of members nnode = 0; % number of balanced (interior) nodes membs = []; % vector of members nodes = []; % vector of nodes supinit = 0; % left end support condition supend = 1; % right end support condition totalLen = 0; % total length decplc = 1; % number of decimal places for moments numSteps = 0; % number of iterative Cross steps stepVector = []; % vector of Cross steps end
Class (constant) properties
properties (Constant) maxNumSteps = 50; % maximum number of iterative Cross steps end
Constructor method
methods %------------------------------------------------------------------ function cross = CrossSolver(nmemb,supinit,supend,decplc,EI,len,q) if (nargin > 0) cross.nmemb = nmemb; cross.nnode = nmemb - 1; membs(1,cross.nmemb) = CrossMember(); for i = 1:cross.nmemb membs(i).EI = EI(i); membs(i).len = len(i); membs(i).q = q(i); end cross.membs = membs; nodes(1,cross.nnode) = CrossNode(); cross.nodes = nodes; cross.supinit = supinit; cross.supend = supend; cross.decplc = decplc; else cross.nmemb = 3; cross.nnode = 2; membs(1,cross.nmemb) = CrossMember(); membs(1).EI = 10000; membs(1).len = 8; membs(1).q = 8; membs(2).EI = 10000; membs(2).len = 6; membs(2).q = 38; membs(3).EI = 10000; membs(3).len = 6; membs(3).q = 28; cross.membs = membs; nodes(1,cross.nnode) = CrossNode(); cross.nodes = nodes; cross.supinit = 0; cross.supend = 1; cross.decplc = 1; end cross.initStiffness(); cross.initNodes(); cross.updateTotalLen(); cross.numSteps = 0; stepVector(1,cross.maxNumSteps) = CrossStep(); cross.stepVector = stepVector; end end
Public methods
methods %------------------------------------------------------------------ % Initializes member stiffness coefficients. function cross = initStiffness(cross) if cross.supinit == 0 %%%%%%% COMPLETE HERE - CROSS_SOLVER: 01 %%%%%%% else %%%%%%% COMPLETE HERE - CROSS_SOLVER: 02 %%%%%%% end if cross.supend == 0 %%%%%%% COMPLETE HERE - CROSS_SOLVER: 03 %%%%%%% else %%%%%%% COMPLETE HERE - CROSS_SOLVER: 04 %%%%%%% end for i = 2:cross.nmemb-1 %%%%%%% COMPLETE HERE - CROSS_SOLVER: 05 %%%%%%% end end %------------------------------------------------------------------ % Initializes nodes: compute moment distribution coefficients and % carry-over factors. function cross = initNodes(cross) % Compute moment distribution coefficients of each node for i = 1:cross.nnode cross.nodes(i).rot = 0; %%%%%%% COMPLETE HERE - CROSS_SOLVER: 06 %%%%%%% end % Compute moment transmission coefficients of each node for i = 1:cross.nnode %%%%%%% COMPLETE HERE - CROSS_SOLVER: 07 %%%%%%% end if cross.supinit == 0 %%%%%%% COMPLETE HERE - CROSS_SOLVER: 08 %%%%%%% end if cross.supend == 0 %%%%%%% COMPLETE HERE - CROSS_SOLVER: 09 %%%%%%% end end %------------------------------------------------------------------ % Sets number of decimal places for moments. % Input arguments: % decplc: number of decimal places for moments. function cross = setMomentToler(cross,decplc) cross.decplc = decplc; end %------------------------------------------------------------------ % Initializes member moments with fixed end values. function cross = initMoments(cross) len = cross.membs(1).len; len2 = len * len; q = cross.membs(1).q; if cross.supinit == 0 %%%%%%% COMPLETE HERE - CROSS_SOLVER: 10 %%%%%%% else %%%%%%% COMPLETE HERE - CROSS_SOLVER: 11 %%%%%%% end len = cross.membs(cross.nmemb).len; len2 = len * len; q = cross.membs(cross.nmemb).q; if cross.supend == 0 %%%%%%% COMPLETE HERE - CROSS_SOLVER: 12 %%%%%%% else %%%%%%% COMPLETE HERE - CROSS_SOLVER: 13 %%%%%%% end for i = 2:cross.nmemb-1 len = cross.membs(i).len; len2 = len * len; q = cross.membs(i).q; %%%%%%% COMPLETE HERE - CROSS_SOLVER: 14 %%%%%%% end % Reset number of iterative Cross steps cross.numSteps = 0; end %------------------------------------------------------------------ % Reset all nodes rotations. function resetNodeRotations(cross) for i = 1:cross.nnode cross.nodes(i).rot = 0; end end %------------------------------------------------------------------ % Update total continous beam length. function updateTotalLen(cross) cross.totalLen = 0; for i = 1:cross.nmemb cross.totalLen = cross.totalLen + cross.membs(i).len; end end %------------------------------------------------------------------ % Checks if node is unbalanced function flag = isNodeUnbalanced(cross,n) momtol = 10^-(cross.decplc+1); % tol. for check unbalanced moment unbal = cross.membs(n).mr + cross.membs(n+1).ml; if abs(unbal) > momtol flag = true; else flag = false; end end %------------------------------------------------------------------ % Gets the node of continuous beam that has the maximum absolute % value of unbalanced moment. % Output: % n: index of the found node. If all the nodes have unbalanced % moment value below current moment tolerance, returns a % non-valid null (0) index. function n = getMaxUnbalNode(cross) momtol = 10^-(cross.decplc+1); % tol. for check unbalanced moment maxunbal = momtol; n = 0; for i = 1:cross.nnode unbal = cross.membs(i).mr + cross.membs(i+1).ml; if abs(unbal) > maxunbal n = i; maxunbal = abs(unbal); end end end %------------------------------------------------------------------ % Performs one iterative step of the Cross Process of a continuous % beam. Distributes the unbalanced moment of a given node among % the two adjacent beam sections. Transmits the carry-over % portions of the balancing moments to the opposite ends of the % adjacent members. % Input arguments: % n: is the index of the target node to be processed function cross = processNode(cross,n) % unbal: unbalanced moment % bml: balancing moment at left of node % bmr: balancing moment at right of node % tml: carry-over moment at left of node % tmr: carry-over moment at right of node % drot: node rotation increment %%%%%%% COMPLETE HERE - CROSS_SOLVER: 15 %%%%%%% % Increment iterative Cross step vector cross.numSteps = cross.numSteps + 1; cross.stepVector(cross.numSteps).n = n; cross.stepVector(cross.numSteps).bml = bml; cross.stepVector(cross.numSteps).bmr = bmr; cross.stepVector(cross.numSteps).tml = tml; cross.stepVector(cross.numSteps).tmr = tmr; % Update node rotation drot = - unbal / (cross.membs(n).k + cross.membs(n+1).k); cross.nodes(n).rot = cross.nodes(n).rot + drot; end %------------------------------------------------------------------ % Solves one step of Cross Process for continuous beams for a given % node. If the node index is not valid, returns a false (0) status % flag. If the target node unbalaced moment absolute value is % less than the current moment tolerance, returns a false (0) % status flag. Otherwise returns a true (1) status flag. % Input arguments: % n: is the index of the target node to be processed function status = nodeStepSolver(cross,n) status = 0; if n < 1 || n > cross.nnode return end momtol = 10^-(cross.decplc+1); % tol. for check unbalanced moment unbal = cross.membs(n).mr + cross.membs(n+1).ml; if abs(unbal) < momtol return end cross.processNode(n); status = 1; end %------------------------------------------------------------------ % Checks to see whether there is more Cross steps to go: returns a % true (1) status if there is at least one step to go; returns a % false (1) status otherwise. function status = moreStepsToGo(cross) status = 0; n = cross.getMaxUnbalNode(); if n > 0 status = 1; end end %------------------------------------------------------------------ % Solves one step of Cross Process for continuous beams: solve the % node with maximum absolute value of unbalanced moment. function status = autoStepSolver(cross) status = 0; n = cross.getMaxUnbalNode(); if n > 0 cross.processNode(n); status = 1; end end %------------------------------------------------------------------ % Processes direct solver of Cross Process for continuous beams. function cross = goThruSolver(cross) cross.initMoments(); cross.resetNodeRotations(); while cross.autoStepSolver() ~= 0 end end %------------------------------------------------------------------ % Prints continuous beam model information. % Input arguments: % out: integer identifier of the output text file function cross = printModelInfo(cross,out) fprintf(out, '\n=========================================================\n'); fprintf(out, ' CROSS - Cross Process of Continuous Beam\n'); fprintf(out, ' PONTIFICAL CATHOLIC UNIVERSITY OF RIO DE JANEIRO\n'); fprintf(out, ' DEPARTMENT OF CIVIL AND ENVIRONMENTAL ENGINEERING\n'); fprintf(out, ' \n'); fprintf(out, ' CIV2801 - FUNDAMENTOS DE COMPUTACAO GRAFICA APLICADA\n'); fprintf(out, '=========================================================\n'); fprintf(out, '\n\n\n____________ M O D E L I N F O R M A T I O N ____________\n'); fprintf(out, ' MEMBERS EI [kNm^2] HINGEi HINGEf LENGTH [m] Distrib. Load [kN/m]\n'); for i = 1:cross.nmemb if i == 1 && cross.supinit == 0 hingei = 'yes'; else hingei = 'no'; end if i == cross.nmemb && cross.supend == 0 hingef = 'yes'; else hingef = 'no'; end EI = cross.membs(i).EI; len = cross.membs(i).len; q = cross.membs(i).q; fprintf(out, '%5d %9d %12s %6s %6.2f %15.2f\n', ... i, EI, hingei, hingef, len, q); end end %------------------------------------------------------------------ % Prints analysis results. % Input arguments: % out: integer identifier of the output text file function cross = printResults(cross,out) fprintf(out, '\n____________ M E M B E R M O M E N T S ____________\n'); fprintf(out, ' MEMBERS Mom.Init [kNm] Mom.End [kNm]\n'); for i = 1:cross.nmemb ml = cross.membs(i).ml; mr = cross.membs(i).mr; ml_txt = sprintf('%.*f',cross.decplc,ml); mr_txt = sprintf('%.*f',cross.decplc,mr); fprintf(out, '%5d %15s %16s\n', i, ml_txt, mr_txt); end end %------------------------------------------------------------------ % Cleans data structure of a CrossSolver object. function cross = clean(cross) cross.nmemb = 0; cross.nnode = 0; cross.membs = []; cross.nodes = []; cross.supinit = 0; cross.supend = 0; cross.totalLen = 0; cross.decplc = 2; cross.numSteps = 0; cross.stepVector = []; end end
end