function performSolverPrecheck(self, checkics)
% performSolverPrecheck Perform sanity checks before solving the PDE
%

% Copyright 2015-2021 The MathWorks, Inc.

% Run the checks, the PDEModel should have
%     Geometry
%     Mesh
%     BCs
%     Coefficients
%

if isa(self,'pde.PDEModel')
    
    if isempty(self.Geometry)
        error(message('pde:pdeModel:noGeometry'));
    end
    
    if isempty(self.Mesh)
        error(message('pde:pdeModel:noMesh'));
    end
    
    
    if checkics && self.IsTimeDependent && isempty(self.InitialConditions)
        error(message('pde:pdeModel:noICs'));
    end
    
    if isempty(self.EquationCoefficients)
        error(message('pde:pdeModel:noCoefficients'));
    end
    self.EquationCoefficients.performSolverPrechecks();
    
end

if isa(self,'pde.ThermalModel')
    
    if isempty(self.Geometry)
        error(message('pde:ThermalModel:thermalModelHasNoGeom'));
    end
    
    if contains(self.AnalysisType,'axisymmetric')
        checkAxisymmetricGeometry(self.Geometry);
    end
    
    if isempty(self.Mesh)
        error(message('pde:ThermalModel:noMesh'));
    end
    
    if isempty(self.MaterialProperties)
        error(message('pde:ThermalModel:noThermalProperties'));
    end
    
    if ~isempty(self.HeatSources)
        self.HeatSources.performSolverPrechecks;
    end
    self.MaterialProperties.performSolverPrechecks();
    
    if checkics && self.IsTimeDependent && isempty(self.InitialConditions)
        error(message('pde:ThermalModel:noICs'));
    end
    

end


if isa(self,'pde.StructuralModel')
    
    if isempty(self.Geometry)
        error(message('pde:StructuralModel:structuralModelHasNoGeom'));
    end
    
    if contains(self.AnalysisType,'axisymmetric')
        checkAxisymmetricGeometry(self.Geometry);
    end
    
    if isempty(self.Mesh)
        error(message('pde:StructuralModel:noMesh'));
    end
    
    if isempty(self.MaterialProperties)
        error(message('pde:ElectromagneticModel:noProperties'));
    end
    self.MaterialProperties.performSolverPrechecks();

    if ~isempty(self.BodyLoads)
        if ~isempty([self.BodyLoads.BodyLoadAssignments(:).GravitationalAcceleration]) || ...
                ~isempty([self.BodyLoads.BodyLoadAssignments(:).AngularVelocity])
            massEmpty = ~any([self.MaterialProperties.MaterialAssignments(:).MassDensity]);
            if massEmpty
                error(message('pde:StructuralModel:noMassDensityForGrav'));
            end
        end
        self.BodyLoads.performSolverPrechecks();
    end
    
    if ~isempty(self.DampingModels)
        self.DampingModels.performSolverPrechecks();
    end
    
    if checkics && self.IsTimeDependent && isempty(self.InitialConditions)
        error(message('pde:StructuralModel:noICs'));
    end
    
    
end

if isa(self,'pde.ElectromagneticModel')
    
    if isempty(self.Geometry)
        error(message('pde:pdeModel:noGeometry'));
    end
    
    if contains(self.AnalysisType,'axisymmetric')
        checkAxisymmetricGeometry(self.Geometry);
    end

    if contains(self.AnalysisType,'electrostatic') && isempty(self.VacuumPermittivity)
        error(message('pde:ElectromagneticModel:missingVacuumPermittivity'));
    end

    if contains(self.AnalysisType,'magnetostatic') && isempty(self.VacuumPermeability)
        error(message('pde:ElectromagneticModel:missingVacuumPermeability'));
    end

    if isempty(self.Mesh)
        error(message('pde:pdeModel:noMesh'));
    end
    
    if isempty(self.MaterialProperties)
        error(message('pde:ElectromagneticModel:noProperties'));
    end
    
    self.MaterialProperties.performSolverPrechecks();
    if ~isempty(self.Sources)
        self.Sources.performSolverPrechecks;
    end
    if ~isempty(self.BoundaryConditions)
        self.BoundaryConditions.performSolverPrechecks;
    end

end


 if checkics && ~isempty(self.InitialConditions)
      self.InitialConditions.performSolverPrechecks();
 end
    

end


function checkAxisymmetricGeometry(gm)
%Helper function to check intersection of the geometry with the axis of rotation.
if isa(gm,'pde.DiscreteGeometry')
    bBox  =  boundingBox(gm);
    minx = bBox(1,1);
    
    if minx < 0
        error(message('pde:StructuralModel:AxsymGeomNotInPositiveRPlane'))
    end
end

if isa(gm,'pde.AnalyticGeometry')
    tempModel = createpde;
    tempModel.Geometry = gm;
    msh = generateMesh(tempModel);
    if any(msh.Nodes(1,:)<0)
        error(message('pde:StructuralModel:AxsymGeomNotInPositiveRPlane'))
    end
end
end
        