function sc = electromagneticSource(self,sourceInput)
%electromagneticSource - Apply source excitation to ElectromagneticModel
%   sc = electromagneticSource(emagmodel,PROPERTY,VALUE) assigns an
%   electromagnetic source to an electromagnetic model. Specify VALUE as a
%   number for constant source or a MATLAB function for a nonconstant source.
%
%    PROPERTY           VALUE
%-------------------------------------------------------------------------
%   'ChargeDensity'    Electric charge density as source 
%   'CurrentDensity'   Electric current density as source
%   'Magnetization'    Magnetization as a source
% -------------------------------------------------------------------------
%
%  sc = electromagneticSource(__,'Face',FACEID) assigns source for the
%  specified face of a 2-D geometry. FACEID is a positive integer not
%  exceeding the number of faces in the geometry.
%
%  sc = electromagneticSource(__,'Cell',CELLID) assigns source for the
%  specified cell of a 3-D geometry. CELLID is a positive integer not
%  exceeding the number of cells in the geometry.
%
%   Example 1: Specify current density for a magnetostatic analysis.
%
%       emagmodel = createpde('electromagnetic','magnetostatic');
%       gm = importGeometry(emagmodel,'PlateHolePlanar.stl');
%       sc = electromagneticSource(emagmodel,'CurrentDensity',10);
%
% See also pde.ElectromagneticModel, pde.ElectromagneticModel/electromagneticProperties,
%          pde.ElectromagneticModel/electromagneticBC, pde.ElectromagneticModel/solve

% Copyright 2020-2022 The MathWorks, Inc.

arguments
    self pde.ElectromagneticModel
    sourceInput.Face
    sourceInput.Cell
    sourceInput.ChargeDensity
    sourceInput.CurrentDensity
    sourceInput.Magnetization
end

if isempty(self.Geometry)
    error(message('pde:pdeModel:noGeometry'));
end

validDomain = self.validDomain;
invalidDomain = setdiff(self.possibleDomainRegions,validDomain);
maxDomainID = self.maxDomainID;

% Error if source is using cell of 2-D or face for 3-D.
if isfield(sourceInput,invalidDomain) && ~isempty(sourceInput.(invalidDomain))
    error(message('pde:ElectromagneticModel:invalidRegionForSource'))
end

% Global source assignment.
if ~isfield(sourceInput,validDomain)
    sourceInput.(validDomain) = 1:maxDomainID;
end

self.isValidEntityID(sourceInput.(validDomain));

if any(sourceInput.(validDomain) > maxDomainID)
    error(message(['pde:pdeModel:invalid',validDomain,'Index']));
end

if isempty(self.Sources)
    self.Sources = pde.ElectromagneticSourceAssignmentRecords(self);
    self.Sources.SourceAssignments = pde.ElectromagneticSourceAssignment.empty;
end
sc = pde.ElectromagneticSourceAssignment(self.Sources,sourceInput);
self.Sources.SourceAssignments(end+1) = sc;
end
