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 2026
Initially prepared for the course CIV 2801 - Fundamentos de Computação Gráfica, 2025, second term, Department of Civil Engineering, PUC-Rio.
Class definition
classdef CrossSolver < handle
See documentation onhandle 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