function varargout=assembleBoundary(self,varargin)
%assembleBoundary Assembles boundary condition contributions in a PDE problem.
%

%       Copyright 2015-2020 The MathWorks, Inc.

narginchk(1,4);
narg = nargin;

gotu=false;
gottime=false;

if narg>1
    u = varargin{1};
    gotu=true;
end

if narg > 2
    time=varargin{2};
    gottime=true;
end

if narg == 4
    gmat=varargin{3};
else
    gmat = 'HRQG';
end

if ~gotu
    u = [];
end

if ~gottime
    time = [];
end

if isprop(self,'DiscretizedBCs') && ~isempty(self.DiscretizedBCs)
    % Skip to bc matrices computation if bc object exists.
    bcmat = self.DiscretizedBCs.getBCMatrices(u,time,gmat);
    if nargout == 4
        varargout{1} = bcmat.Q;
        varargout{2} = bcmat.G;
        varargout{3} = bcmat.H;
        varargout{4} = bcmat.R;
    else
        varargout{1} = bcmat;
    end
    
    return
end

bl = self;
if isempty(self.BoundaryConditions)
    bc = [];  
else
    % Save packed BC to a dynamic property when solving time-dependent
    % problems to prevent successive packing for each time-step.
    if isprop(self,'PackedBCs') && isempty(self.PackedBCs)
        bc = self.BoundaryConditions.packBoundaryConditions();
        self.PackedBCs = bc;
    elseif isprop(self,'PackedBCs') && ~isempty(self.PackedBCs)
        bc = self.PackedBCs;
    else
        bc = self.BoundaryConditions.packBoundaryConditions();
    end
end

interfaceConditionsPermitted = false;
if isprop(self,'IsThermalStress')
    interfaceConditionsPermitted = true;
end

bcImpl = pde.internal.pde3DBCImpl(bl,bc,true,interfaceConditionsPermitted); % true for R2016b BC implementation
if isprop(self,'DiscretizedBCs') && isempty(self.DiscretizedBCs)
    self.DiscretizedBCs = bcImpl;
end
bcmat = bcImpl.getBCMatrices(u,time,gmat);
if nargout == 4
    varargout{1} = bcmat.Q;
    varargout{2} = bcmat.G;
    varargout{3} = bcmat.H;
    varargout{4} = bcmat.R;
else
    varargout{1} = bcmat;
end

end


