%QMU class definition
%
%   Usage:
%      qmu=qmu();

classdef qmu
	properties (SetAccess=public) 
		isdakota                    = 0;
		variables                   = struct();
		responses                   = struct();
		method                      = struct();
		params                      = struct();
		results                     = struct();
		partition                   = NaN;
		numberofpartitions          = 0;
		numberofresponses           = 0;
		variabledescriptors         = {};
		responsedescriptors         = {};
		mass_flux_profile_directory = NaN;
		mass_flux_profiles          = NaN;
		mass_flux_segments          = {};
		adjacency                   = NaN;
		vertex_weight               = NaN;
	end
	methods
		function obj = qmu(varargin) % {{{
			switch nargin
				case 0
					obj=setdefaultparameters(obj);
				otherwise
					error('constructor not supported');
			end
		end % }}}
		function obj = setdefaultparameters(obj) % {{{

		end % }}}
		function md = checkconsistency(obj,md,solution,analyses) % {{{

			%Early return
			if ~md.qmu.isdakota, return; end

			if md.qmu.params.evaluation_concurrency~=1,
				md = checkmessage(md,['concurrency should be set to 1 when running dakota in library mode']);
			end
			if ~isempty(md.qmu.partition),
				if numel(md.qmu.partition)~=md.mesh.numberofvertices,
					md = checkmessage(md,['user supplied partition for qmu analysis should have size md.mesh.numberofvertices x 1 ']);
				end
				if min(md.qmu.partition)~=0,
					md = checkmessage(md,['partition vector not indexed from 0 on']);
				end
				if max(md.qmu.partition)>=md.qmu.numberofpartitions,
					md = checkmessage(md,['for qmu analysis, partitioning vector cannot go over npart, number of partition areas']);
				end
			end

			if ~strcmpi(md.cluster.name,'none'),
				if md.settings.waitonlock==0,
					md = checkmessage(md,['waitonlock should be activated when running qmu in parallel mode!']);
				end
			end
		end % }}}
		function disp(obj) % {{{
			disp(sprintf('   qmu parameters:'));

			fielddisplay(obj,'isdakota','is qmu analysis activated?');
			for i=1:numel(obj.variables)
				disp(sprintf('         variables%s:  (arrays of each variable class)',...
					string_dim(obj.variables,i)));
				fnames=fieldnames(obj.variables(i));
				maxlen=0;
				for j=1:numel(fnames)
					maxlen=max(maxlen,length(fnames{j}));
				end

				for j=1:numel(fnames)
					disp(sprintf(['            %-' num2str(maxlen+1) 's:    [%ix%i]    ''%s'''],...
						fnames{j},size(obj.variables.(fnames{j})),class(obj.variables.(fnames{j}))));
				end
			end
			for i=1:numel(obj.responses)
				disp(sprintf('         responses%s:  (arrays of each response class)',...
					string_dim(obj.responses,i)));
				fnames=fieldnames(obj.responses(i));
				maxlen=0;
				for j=1:numel(fnames)
					maxlen=max(maxlen,length(fnames{j}));
				end

				for j=1:numel(fnames)
					disp(sprintf(['            %-' num2str(maxlen+1) 's:    [%ix%i]    ''%s'''],...
						fnames{j},size(obj.responses.(fnames{j})),class(obj.responses.(fnames{j}))));
				end
			end
			fielddisplay(obj,'numberofresponses','number of responses') 
			for i=1:numel(obj.method);
				if strcmp(class(obj.method(i)),'dakota_method')
					disp(sprintf('            method%s :    ''%s''',...
						string_dim(obj.method,i),obj.method(i).method));
				end
			end
			for i=1:numel(obj.params)
				disp(sprintf('         params%s:  (array of method-independent parameters)',...
					string_dim(obj.params,i)));
				fnames=fieldnames(obj.params(i));
				maxlen=0;
				for j=1:numel(fnames)
					maxlen=max(maxlen,length(fnames{j}));
				end

				for j=1:numel(fnames)
					disp(sprintf(['            %-' num2str(maxlen+1) 's: %s'],...
						fnames{j},any2str(obj.params(i).(fnames{j}))));
				end
			end
			for i=1:numel(obj.results)
				disp(sprintf('         results%s:  (information from dakota files)',...
					string_dim(obj.results,i)));
				fnames=fieldnames(obj.results(i));
				maxlen=0;
				for j=1:numel(fnames)
					maxlen=max(maxlen,length(fnames{j}));
				end

				for j=1:numel(fnames)
					disp(sprintf(['            %-' num2str(maxlen+1) 's:    [%ix%i]    ''%s'''],...
						fnames{j},size(obj.results.(fnames{j})),class(obj.results.(fnames{j}))));
				end
			end
			fielddisplay(obj,'partition','user provided mesh partitioning, defaults to metis if not specified') 
			fielddisplay(obj,'numberofpartitions','number of partitions for semi-discrete qmu') 
			fielddisplay(obj,'variabledescriptors','');
			fielddisplay(obj,'responsedescriptors','');
			fielddisplay(obj,'method','array of dakota_method class');
			fielddisplay(obj,'mass_flux_profile_directory','directory for mass flux profiles');
			fielddisplay(obj,'mass_flux_profiles','list of mass_flux profiles');
			fielddisplay(obj,'mass_flux_segments','');
			fielddisplay(obj,'adjacency','');
			fielddisplay(obj,'vertex_weight','weight applied to each mesh vertex');

		end % }}}
		function marshall(obj,fid) % {{{
			WriteData(fid,'object',obj,'fieldname','isdakota','format','Boolean');
			if ~obj.isdakota, 
				WriteData(fid,'data',false,'enum',QmuMassFluxSegmentsPresentEnum,'format','Boolean');
				return; 
			end
			WriteData(fid,'object',obj,'fieldname','partition','format','DoubleMat','mattype',2);
			WriteData(fid,'object',obj,'fieldname','numberofpartitions','format','Integer');
			WriteData(fid,'object',obj,'fieldname','numberofresponses','format','Integer');
			WriteData(fid,'object',obj,'fieldname','variabledescriptors','format','StringArray');
			WriteData(fid,'object',obj,'fieldname','responsedescriptors','format','StringArray');
			if ~isempty(obj.mass_flux_segments), 
				WriteData(fid,'data',obj.mass_flux_segments,'enum',MassFluxSegmentsEnum,'format','MatArray');
				flag=true; 
			else 
				flag=false; 
			end
			WriteData(fid,'data',flag,'enum',QmuMassFluxSegmentsPresentEnum,'format','Boolean');
		end % }}}
	end
end
