%% Rigid Assembly of Model Components
% This example shows how to specify rigid physical coupling between the components of a structural model. Consider a structure that consists of two square plates connected with pillars at each vertex as depicted in the figure below. The lower plate is connected rigidly to the ground while the pillars are connected rigidly to each vertex of the square plates.
% For more information on sparse models, see Sparse Model Basics.
%
% platePillarModel.mat contains the sparse matrices for pillar and plate model. Load the finite element model matrices contained in platePillarModel.mat and create the sparse second-order state-space model representing the above system.

load('platePillarModel.mat')
sys = ...
   mechss(M1,[],K1,B1,F1,'Name','Plate1') + ...
   mechss(M2,[],K2,B2,F2,'Name','Plate2') + ...
   mechss(Mp,[],Kp,Bp,Fp,'Name','Pillar3') + ...
   mechss(Mp,[],Kp,Bp,Fp,'Name','Pillar4') + ...
   mechss(Mp,[],Kp,Bp,Fp,'Name','Pillar5') + ...
   mechss(Mp,[],Kp,Bp,Fp,'Name','Pillar6')

% The resultant model sys has 5820 degrees of freedom, one input and one output.
% Use showStateInfo to examine the components of the mechss model object.

showStateInfo(sys)

% The named components are listed in the command window with their respective sizes.
% Now, load the interfaced DOF index data from dofData.mat and use interface to create the physical connections between the two plates and the four pillars. dofs is a 6x7 cell array where the first two rows contain DOF index data for the first and second plate while the remaining four rows contain index data for the four pillars.

load('dofData.mat','dofs')

% Now, specify rigid couplings between the plates and the pillars.

for i=3:6
   sys = interface(sys,"Plate1",dofs{1,i},"Pillar"+i,dofs{i,1});
   sys = interface(sys,"Plate2",dofs{2,i},"Pillar"+i,dofs{i,2});
end

% Specify rigid connection between the bottom plate and the ground.

sysCon = interface(sys,"Plate2",dofs{2,7})

% Notice that the model now contains 5922 degrees of freedom. The extra DOFs are a result of the specific rigid interfaces.
% interface uses 'dual assembly' formulation to connect the components. In the concept of dual assembly, the global set of degrees of freedom (DoFs) q is retained and the physical coupling is expressed as consistency and equilibrium constraints at the interface. For rigid connections, these constraints are of the form:
% Bq=0,\;\;\;\;\;\;\;\;\;\;g=-B^T\lambda
% where g is the vector of internal forces at the interface, and the matrix B is permutable to \left\lbrack I\;\;-I\right\rbrack. For a pair of matching DOFs with indices i_i, i_2 where i_i selects a DOF in the first component while i_2 selects the matching DOF in the second component, Bq=0 enforces consistency of displacements:
% q\left(i_1\right)=q\left(i_2\right)
% while g=-B^T\lambda enforces equilibrium of the internal forces g at the interface:
% g\left(i_1\right)+g\left(i_2\right)=0.
% Combining these constrains with the uncoupled equations M\ddot{q}+C\dot{q}+Kq=f+g leads to the following dual assembly model for the coupled system:
% \left[ \begin{array}{cc}
% M & 0\\
% 0 & 0 \end{array} \right]
% \left[ \begin{array}{c}
% \ddot{q}\\
% \lambda\end{array} \right]+
% \left[ \begin{array}{cc}
% C & 0\\
% 0 & 0 \end{array} \right]\left[ \begin{array}{cc}
% \dot{q}\\
% \lambda\end{array} \right]+\left[ \begin{array}{cc}
% K & B^T\\
% B & 0 \end{array} \right]\left[ \begin{array}{cc}
% q\\
% \lambda \end{array} \right]=\left[ \begin{array}{cc}
% f\\
% 0 \end{array} \right]
% For more information, see interface.
% Use showStateInfo to confirm the physical connections.

showStateInfo(sysCon)

% You can use spy to visualize the sparse matrices in the final model. Choose between the matrices to be displayed using the display menu that can be accessed by right-clicking on the plot.

spy(sysCon)

%
%% Acknowledgements
% The data set for this example was provided by Victor Dolk from ASML.
% Copyright 2020 The MathWorks, Inc.