Anm_Grillage Class

This is a sub-class, in the Object Oriented Programming (OOP) paradigm, of super-class Anm in the LESM (Linear Elements Structure Model) program. This sub-class implements abstract methods, declared in super-class Anm, that deal with grillage analysis model of linear structure elements.

Contents

Grillage Analysis

A grillage model is a common form of analysis model for building stories and bridge decks. Its key features are:

Class definition

Definition of sub-class Anm_Grillage derived from super-class Anm.

classdef Anm_Grillage < Anm

Constructor method

    methods
 
        %------------------------------------------------------------------
        function anm = Anm_Grillage()
            include_constants;
            anm = anm@Anm(GRILLAGE_ANALYSIS,3);
        end
    end

Public methods

Implementation of the abstract methods declared in super-class Anm.

    methods
 
        %------------------------------------------------------------------
        % Assembles element d.o.f. (degree of freedom) rotation transformation
        % matrix from global system to local system.
        % Output:
        %  rot: rotation transformation matrix
        % Input arguments:
        %  elem: handle to an object of the Elem class
        function rot = gblToLocElemRotMtx(~,elem)
            % Get 3x3 basis rotation transformation matrix
            T = elem.T;

            % Assemble element d.o.f. rotation transformation matrix
            % rot = [ T 0
            %         0 T ]
            rot = blkdiag(T,T);
        end

 
        %------------------------------------------------------------------
        % Initializes global d.o.f (degree of freedom) numbering ID matrix
        % with ones and zeros, and counts total number of equations of free
        % d.o.f.'s and total number of equations of fixed d.o.f.'s.
        %  ID matrix initialization:
        %  if ID(k,n) = 0, d.o.f. k of node n is free.
        %  if ID(k,n) = 1, d.o.f. k of node n is constrained by support.
        % Input arguments:
        %  drv: handle to an object of the Drv class
        function setupDOFNum(anm,drv)
            include_constants;

            % Dimension global d.o.f. numbering ID matrix
            drv.ID = zeros(anm.ndof,drv.nnp);

            % Initialize number of fixed d.o.f.
            drv.neqfixed = 0;

            % Count number of fixed d.o.f. and setup ID matrix
            for n = 1:drv.nnp

                % Check for fixed rotation about global X direction
                if drv.nodes(n).ebc(4) ~= FREE_DOF
                    drv.neqfixed = drv.neqfixed + 1;
                    drv.ID(1,n) = 1;
                end

                % Check for fixed rotation about global Y direction
                if drv.nodes(n).ebc(5) ~= FREE_DOF
                    drv.neqfixed = drv.neqfixed + 1;
                    drv.ID(2,n) = 1;
                end

                % Check for fixed translation in global Z direction
                if drv.nodes(n).ebc(3) ~= FREE_DOF
                    drv.neqfixed = drv.neqfixed + 1;
                    drv.ID(3,n) = 1;
                end
            end

            % Compute total number of free d.o.f.
            drv.neqfree = drv.neq - drv.neqfixed;
        end

 
        %------------------------------------------------------------------
        % Adds prescribed displacements (known support settlement values)
        % to global displacement vector.
        % Avoids storing a prescribed displacement component in a position
        % of the global displacement vector that corresponds to a free d.o.f.
        % Input arguments:
        %  drv: handle to an object of the Drv class
        function setupPrescDispl(~,drv)
            for n = 1:drv.nnp
                if ~isempty(drv.nodes(n).prescDispl)

                    % Add prescribed rotation about global X direction
                    id = drv.ID(1,n);
                    if (id > drv.neqfree) && (drv.nodes(n).prescDispl(4) ~= 0)
                        drv.D(id) = drv.nodes(n).prescDispl(4);
                    end

                    % Add prescribed rotation about global Y direction
                    id = drv.ID(2,n);
                    if (id > drv.neqfree) && (drv.nodes(n).prescDispl(5) ~= 0)
                        drv.D(id) = drv.nodes(n).prescDispl(5);
                    end

                    % Add prescribed displacement in global Z direction
                    id = drv.ID(3,n);
                    if (id > drv.neqfree) && (drv.nodes(n).prescDispl(3) ~= 0)
                        drv.D(id) = drv.nodes(n).prescDispl(3);
                    end

                end
            end
        end

 
        %------------------------------------------------------------------
        % Assembles element stiffness matrix in local system.
        % Output:
        %  kel: target element stiffness matrix in local system
        % Input arguments:
        %  elem: handle to an object of the Elem class
        function kel = elemLocStiffMtx(~,elem)
            % Compute torsion stiffness coefficients
            ket = elem.torsionStiffCoeff();

            % Compute flexural stiffness coefficients
            kef = elem.flexuralStiffCoeff_XZ();

            % Assemble element stiffness matrix in local system
            kel = [ ket(1,1)  0         0         ket(1,2)  0         0;
                    0         kef(2,2)  kef(2,1)  0         kef(2,4)  kef(2,3);
                    0         kef(1,2)  kef(1,1)  0         kef(1,4)  kef(1,3);
                    ket(2,1)  0         0         ket(2,2)  0         0;
                    0         kef(4,2)  kef(4,1)  0         kef(4,4)  kef(4,3);
                    0         kef(3,2)  kef(3,1)  0         kef(3,4)  kef(3,3) ];
        end

 
        %------------------------------------------------------------------
        % Adds nodal load components to global forcing vector,
        % including the terms that correspond to constrained d.o.f.
        % Input arguments:
        %  drv: handle to an object of the Drv class
        function nodalLoads(~,drv)
            for n = 1:drv.nnp
                if ~isempty(drv.nodes(n).nodalLoad)

                    % Add applied moment about global X direction
                    id = drv.ID(1,n);
                    drv.F(id) = drv.F(id) + drv.nodes(n).nodalLoad(4);

                    % Add applied moment about global Y direction
                    id = drv.ID(2,n);
                    drv.F(id) = drv.F(id) + drv.nodes(n).nodalLoad(5);

                    % Add applied force in global Z direction
                    id = drv.ID(3,n);
                    drv.F(id) = drv.F(id) + drv.nodes(n).nodalLoad(3);

                end
            end
        end

 
        %------------------------------------------------------------------
        % Assembles element fixed end force (FEF) vector in local system
        % for an applied distributed load.
        % Output:
        %  fel: element fixed end force vector in local system
        % Input arguments:
        %  load: handle to an object of the Lelem class
        function fel = elemLocDistribLoadFEF(~,load)
            % Compute flexural (transversal) fixed end force components
            fef = load.flexuralDistribLoadFEF_XZ();

            % Assemble element fixed end force (FEF) vector in local system
            fel = [ 0;
                    fef(2);
                    fef(1);
                    0;
                    fef(4);
                    fef(3) ];
        end

 
        %------------------------------------------------------------------
        % Assembles element fixed end force (FEF) vector in local system
        % for an applied thermal load (temperature variation).
        % Output:
        %  fel: element fixed end force vector in local system
        % Input arguments:
        %  load: handle to an object of the Lelem class
        function fel = elemLocThermalLoadFEF(~,load)
            % Compute flexural (transversal) fixed end force components
            fef = load.flexuralThermalLoadFEF_XZ();

            % Assemble element fixed end force (FEF) vector in local system
            fel = [ 0;
                    fef(2);
                    fef(1);
                    0;
                    fef(4);
                    fef(3) ];
        end

 
        %------------------------------------------------------------------
        % Initializes element internal forces arrays with null values.
        %  torsion_moment(1,2)
        %   Ti = torsion_moment(1) - init value
        %   Tf = torsion_moment(2) - final value
        %  bending_moment(1,2)
        %   Mi = bending_moment(1) - init value
        %   Mf = bending_moment(2) - final value
        %  shear_force(1,2)
        %   Qi = shear_force(1) - init value
        %   Qf = shear_force(2) - final value
        % Input arguments:
        %  elem: handle to an object of the Elem class
        function initIntForce(~,elem)
            elem.torsion_moment   = zeros(1,2);
            elem.bending_moment_Y = zeros(1,2);
            elem.shear_force_Z    = zeros(1,2);
        end

 
        %------------------------------------------------------------------
        % Assembles contribution of a given internal force vector to
        % element arrays of internal forces.
        % Input arguments:
        %  elem: handle to an object of the Elem class
        %  fel: element internal force vector in local system
        function assembleIntForce(~,elem,fel)
            elem.torsion_moment(1)   = elem.torsion_moment(1)   + fel(1);
            elem.torsion_moment(2)   = elem.torsion_moment(2)   + fel(4);
            elem.bending_moment_Y(1) = elem.bending_moment_Y(1) + fel(2);
            elem.bending_moment_Y(2) = elem.bending_moment_Y(2) + fel(5);
            elem.shear_force_Z(1)    = elem.shear_force_Z(1)    + fel(3);
            elem.shear_force_Z(2)    = elem.shear_force_Z(2)    + fel(6);
        end

 
        %------------------------------------------------------------------
        % Initializes element internal displacements array with null values.
        % Each element is discretized in 50 cross-sections, where internal
        % displacements are computed.
        %  intDispl(1,:) -> du (axial displacement)
        %  intDispl(2,:) -> dw (transversal displacement in local z-axis)
        % Input arguments:
        %  elem: handle to an object of the Elem class
        function initIntDispl(~,elem)
            elem.intDispl = zeros(2,50);
        end

 
        %------------------------------------------------------------------
        % Assembles displacement shape function matrix evaluated at a
        % given cross-section position.
        % Output:
        %  N: displacement shape function matrix
        % Input arguments:
        %  elem: handle to an object of the Elem class
        %  x: cross-section position on element local x-axis
        function N = displShapeFcnMtx(~,elem,x)
            % Compute transversal displacement shape functions vector
            Nw = elem.flexuralDisplShapeFcnVector_XZ(x);

            % Assemble displacement shape function matrix
            N = [ 0      0      0      0      0      0;
                  0      Nw(2)  Nw(1)  0      Nw(4)  Nw(3) ];
        end

 
        %------------------------------------------------------------------
        % Computes element internal displacements vector in local system,
        % in a given cross-section position, for the local analysis from
        % element loads (distributed loads and thermal loads).
        % Output:
        %  del: a 2x1 vector of with element internal displacements:
        %      du -> axial displacement (always zero)
        %      dw -> transversal displacement in local z-axis direction
        %      x  -> cross-section position on element local x-axis
        %  del = [ du(x);
        %          dw(x) ]
        % Input arguments:
        %  elem: handle to an object of the Elem class
        %  x: cross-section position on element local x-axis
        function del = lclAnlIntDispl(~,elem,x)
            % Initialize displacements vector resulting from local analysis
            del = [ 0;
                    0 ];

            % Add the contribution of transversal displacements resulting
            % from distributed loads (there is no axial displacement in a
            % grillage model)
            if (~isempty(elem.load.uniformLcl)) || (~isempty(elem.load.linearLcl))
                del(2) = elem.load.flexuralDistribLoadDispl_XZ(x);
            end

            % Add the contribution of transversal displacements resulting
            % from thermal loads (there is no axial displacement in a
            % grillage model)
            if (elem.load.tempVar_X ~= 0) || (elem.load.tempVar_Z ~= 0)
                del(2) = del(2) + elem.load.flexuralThermalLoadDispl_XZ(x);
            end
        end
    end
end