%SOLVER class definition
%
%   Usage:
%      obj=solver();

classdef solver < dynamicprops
    properties (SetAccess=public) 
		 NoneAnalysis = struct();
		 %The other properties are dynamic
	 end
	 methods
		 function obj = solver(varargin) % {{{
			 switch nargin
				 case 0
					 obj=setdefaultparameters(obj);
				 otherwise
					 error('constructor not supported');
				 end
			 end % }}}
		 function obj = addoptions(obj,analysis,varargin) % {{{
		 % Usage example:
		 %    md.solver=addoptions(md.solver,DiagnosticHorizAnalysisEnum(),stokesoptions());
		 %    md.solver=addoptions(md.solver,DiagnosticHorizAnalysisEnum());

			 %Convert analysis from enum to string
			 analysis=EnumToString(analysis);

			 %Create dynamic property if property does not exist yet
			 if ~ismember(analysis,properties(obj)),
				 obj.addprop(analysis);
			 end

			 %Add solver options to analysis
			 if nargin==3, obj.(analysis) = varargin{1}; end
		 end
		 %}}}
		 function obj = setdefaultparameters(obj) % {{{

			 %MUMPS is the default solver
			 if ismumps(),
				 obj.NoneAnalysis=mumpsoptions();
			 else
				 obj.NoneAnalysis=iluasmoptions();
			 end

		 end % }}}
		 function disp(obj) % {{{
			 analyses=properties(obj);
			 disp(sprintf('List of solver options per analysis:\n'));
			 for i=1:numel(analyses),
				 analysis=analyses{i};
				 disp([analysis ':']);
				 disp(obj.(analysis));
			 end
		 end % }}}
		 function md = checkconsistency(obj,md,solution,analyses) % {{{
			 analyses=properties(obj);
			 for i=1:numel(analyses),
				 if isempty(fieldnames(obj.(analyses{i})))
					 md = checkmessage(md,['md.solver.' analyses{i} ' is empty']);
				 end
			 end
		 end % }}}
		 function PetscFile(solver,filename) % {{{
		 %PETSCFILE - build petsc file
		 %
		 %   Build a Petsc compatible options file, from the solver model field  + return options string
		 %
		 %   Usage:     PetscFile(solver,filename);

			 %open file for writing
			 fid=fopen(filename,'w');
			 if fid==-1,
				 error(['PetscFile error: could not open ' filename ' for writing']);
			 end

			 %write header
			 fprintf(fid,'%s%s%s\n','%Petsc options file: ',filename,' written from Matlab solver array');

			 %start writing options
			 analyses=properties(solver);
			 for i=1:numel(analyses),
				 analysis=analyses{i};
				 options=solver.(analysis);

				 %first write analysis:
				 fprintf(fid,'\n+%s\n',analysis); %append a + to recognize it's an analysis enum

				 %now, write options
				 optionslist=fieldnames(options);
				 for j=1:numel(optionslist),
					 optionname=optionslist{j};
					 optionvalue=options.(optionname);

					 if isempty(optionvalue),
						 %this option has only one argument
						 fprintf(fid,'-%s\n',optionname);
					 else
						 %option with value. value can be string or scalar
						 if isnumeric(optionvalue),
							 fprintf(fid,'-%s %g\n',optionname,optionvalue);
						 elseif ischar(optionvalue),
							 fprintf(fid,'-%s %s\n',optionname,optionvalue);
						 else
							 error(['PetscFile error: option ' optionname ' is not well formatted']);
						 end
					 end
				 end
			 end

			 fclose(fid);
		 end %}}}
	 end
 end
