Index: issm/trunk/src/m/classes/qmu/continuous_design.m
===================================================================
--- issm/trunk/src/m/classes/qmu/continuous_design.m	(revision 24686)
+++ issm/trunk/src/m/classes/qmu/continuous_design.m	(revision 25836)
@@ -220,4 +220,6 @@
 			pairs_per_variable=[];
         end % }}}
+		function checkconsistency(self,md,solution,analyses) % {{{
+		end % }}}
 
 	end
Index: issm/trunk/src/m/classes/qmu/histogram_bin_uncertain.m
===================================================================
--- issm/trunk/src/m/classes/qmu/histogram_bin_uncertain.m	(revision 24686)
+++ issm/trunk/src/m/classes/qmu/histogram_bin_uncertain.m	(revision 25836)
@@ -1,68 +1,75 @@
-% %  definition for the histogram_bin_uncertain class.
+%HISTOGRAM BIN UNCERTAIN class definition
 %
-%  [hbu]=histogram_bin_uncertain(varargin)
+%	Usage: 
+%   hbu=histogram_bin_uncertain('descriptor',descriptor,'pairs_per_variable',pairs_per_variable,...
+%           'abscissas',abscissas,'counts',counts,'partition',partition)
+%      
+%      where hbu is the histogram_bin_uncertain object returned by the constructor, pairs_per_variable the 
+%      size of the histogram, 'abscissas' and 'counts' describe the histogram itself. 
+%      If the variable is distributed, then a partition vector can be supplied, which can be a 
+%      partition vector over elements or vertices. In which case counts, 
 %
-%  where the required varargin are:
-%    descriptor    (char, description, '')
-%    pairs_per_variable          (double vector, [])
-%    abscissas          (double vector, [])
-%    counts          (int vector, [])
-%
-%  note that zero arguments constructs a default instance; one
-%  argument of the class copies the instance; and three or more
-%  arguments constructs a new instance from the arguments.
-%
+%   Example:
+%      md.qmu.variables.giaid=histogram_bin_uncertain('descriptor','GiammeModelId','pairs_per_variable',3,...
+%           'count',[.6 .4 0],''abscissas',[1 2 3]);
+%      md.qmu.variables.surfaceloadid=histogram_bin_uncertain(...
+%           'descriptor','distributed_SurfaceloadModelId','pairs_per_variable',[2 3 4],...
+%           'counts',{[1 0],[.6 .4 0],[.4 .4 .2 0]},...
+%           'abscissas',{[1 2],[1 2 3],[1 2 3 4]},...
+%           'partition',partition_vector);
+
 classdef histogram_bin_uncertain
-    properties
-        descriptor='';
-		pairs_per_variable=[];
-        abscissas = [];
-        counts = [];
-    end
+	properties
+		descriptor='';
+		pairs_per_variable={};
+		abscissas = {};
+		counts = [];
+		partition=[];
+	end
+	methods
+		function self=histogram_bin_uncertain(varargin) % {{{
+		
+			%recover options:
+			options=pairoptions(varargin{:});
 
-    methods
-        function [hbu]=histogram_bin_uncertain(varargin) % {{{
+			%initialize fields:
+			self.descriptor=getfieldvalue(options,'descriptor');
+			self.pairs_per_variable=getfieldvalue(options,'pairs_per_variable');
+			self.abscissas=getfieldvalue(options,'abscissas');
+			self.counts=getfieldvalue(options,'counts');
 
-            switch nargin
-                case 0 %  create a default object
-                case 1 %  copy the object
-                    if isa(varargin{1},'histogram_bin_uncertain')
-                        hbu=varargin{1};
-                    else
-                        error('Object ''%s'' is a ''%s'' class object, not ''%s''.',...
-                            inputname(1),class(varargin{1}),'histogram_bin_uncertain');
-                    end
-                case {2,3} %  not enough arguments
-                    error('Construction of ''%s'' class object requires at least %d inputs.',...
-                        'histogram_bin_uncertain',4)
-                case 4 % 
-					%  create the object from the input
-					hbu = histogram_bin_uncertain; 
-					hbu.descriptor=varargin{1};
-					hbu.pairs_per_variable=varargin{2};
-					hbu.abscissas=varargin{3};
-					hbu.counts=varargin{4};
-
-                otherwise 
-					error('Construction of histogram_bin_uncertain class object requires three arguments, descriptor, abscissas and counts');
-            end
-
-        end % }}}
-        function []=disp(hbu) % {{{
-
-%  display the object
-
-            disp(sprintf('\n'));
-            for i=1:numel(hbu)
-                disp(sprintf('class ''%s'' object ''%s%s'' = \n',...
-                    class(hbu),inputname(1),string_dim(hbu,i)));
-                disp(sprintf('    descriptor: ''%s'''  ,hbu(i).descriptor));
-                disp(sprintf('          pairs_per_variable: %g'      ,hbu(i).pairs_per_variable));
-                disp(sprintf('          abscissas: %g'      ,hbu(i).abscissas));
-                disp(sprintf('        counts: %g'      ,hbu(i).counts));
-            end
-
-        end % }}}
-        function [desc]  =prop_desc(hbu,dstr) % {{{ 
+			%if the variable is distributed,  a partition vector should have been 
+			%supplied, and that partition vector should have as many partitions 
+			%as the pairs_per_variable, abscissas and counts arrays: 
+			if self.isdistributed(),
+				self.partition=getfieldvalue(options,'partition');
+				npart=qmupart2npart(self.partition);
+				if npart~=length(self.pairs_per_variable),
+					error(sprintf('histogram_bin_uncertain constructor: for the distributed variable  %s the number of pairs_per_variable arrays (%i) should be equal to the number of partitions (%i)',self.descriptor,length(self.pairs_per_variable),npart));
+				end
+				if npart~=length(self.abscissas),
+					error(sprintf('histogram_bin_uncertain constructor: for the distributed variable  %s the number of abscissas arrays (%i) should be equal to the number of partitions (%i)',self.descriptor,length(self.abscissas),npart));
+				end
+				if npart~=length(self.counts),
+					error(sprintf('histogram_bin_uncertain constructor: for the distributed variable  %s the size of counts (%i) should be equal to the number of partitions (%i)',self.descriptor,length(self.counts),npart));
+				end
+			end
+		end % }}}
+		function md=checkconsistency(self,md,solution,analyses) % {{{
+		end % }}}
+			function disp(self) % {{{
+			disp(sprintf('   histogram_bin uncertain variable: '));
+			fielddisplay(self,'descriptor','name tag');
+			fielddisplay(self,'pairs_per_variable','number of bins in histogram');
+			fielddisplay(self,'abscissas','abscissas for histogram');
+			fielddisplay(self,'counts','probabilities for histogram');
+			if ~isempty(self.partition),
+				fielddisplay(self,'partition','partition vector defining where sampling will occur');
+			end
+		end
+		%}}}
+		%virtual functions needed by qmu processing algorithms:
+		%implemented:
+        function [desc]=prop_desc(hbu,dstr) % {{{ 
             desc=cell(1,numel(hbu));
             for i=1:numel(hbu)
@@ -79,14 +86,5 @@
             desc=allempty(desc);
         end  %}}}
-        function [initpt]=prop_initpt(hbu) % {{{
-            initpt=[];
-        end % }}}
-        function [lower] =prop_lower(hbu) % {{{
-            lower=[];
-        end % }}}
-        function [upper] =prop_upper(hbu) % {{{
-            upper=[];
-        end % }}}
-        function [mean]  =prop_mean(hbu) % {{{
+        function [mean]=prop_mean(hbu) % {{{
             mean=[];
         end % }}}
@@ -94,46 +92,63 @@
             stddev=[];
         end % }}}
+        function [lower]=prop_lower(hbu) % {{{
+            lower=[];
+        end % }}}
+        function [upper]=prop_upper(hbu) % {{{
+            upper=[];
+        end % }}}
+		function [pairs_per_variable] =prop_pairs_per_variable(hbu) % {{{
+			pairs_per_variable=[];
+            for i=1:numel(hbu)
+                pairs_per_variable=[pairs_per_variable hbu(i).pairs_per_variable];
+            end
+        end % }}}
+		function [abscissas]=prop_abscissas(hbu) % {{{
+			abscissas=[]; 
+			for i=1:numel(hbu)
+				abscissas=[abscissas hbu(i).abscissas'];
+			end
+			abscissas=allequal(abscissas,-Inf);
+		end % }}}
+   		function [counts] =prop_counts(hbu) % {{{
+			counts=[]; 
+			for i=1:numel(hbu)
+				counts=[counts hbu(i).counts'];
+			end
+			counts=allequal(counts,-Inf);
+        end % }}}
+        function [initpt]=prop_initpt(hbu) % {{{
+            initpt=[];
+        end % }}}
         function [initst]=prop_initst(hbu) % {{{ 
             initst=[];
         end % }}}
-        function [stype] =prop_stype(hbu) % {{{
+        function [stype]=prop_stype(hbu) % {{{
             stype={};
         end % }}}
-        function [scale] =prop_scale(hbu) % {{{
+        function [scale]=prop_scale(hbu) % {{{
             scale=[]; 
         end % }}}
-		function [abscissas] =prop_abscissas(hbu) % {{{
-		abscissas=[]; 
-		for i=1:numel(hbu)
-			abscissas=[abscissas hbu(i).abscissas];
-		end
-		abscissas=allequal(abscissas,-Inf);
-
-        end % }}}
-		function [pairs_per_variable] =prop_pairs_per_variable(hbu) % {{{
-			pairs_per_variable=zeros(1,numel(hbu));
-            for i=1:numel(hbu)
-                pairs_per_variable(i)=hbu(i).pairs_per_variable;
-            end
-            pairs_per_variable=allequal(pairs_per_variable,-Inf);
-        end % }}}
-   		function [counts] =prop_counts(hbu) % {{{
-		counts=[]; 
-		for i=1:numel(hbu)
-			counts=[counts hbu(i).counts];
-		end
-		counts=allequal(counts,-Inf);
-
-        end % }}}
+		function scaled=isscaled(self) % {{{
+			if strncmp(self.descriptor,'scaled_',7),
+				scaled=1;
+			else
+				scaled=0;
+			end
+		end % }}}
+		function distributed=isdistributed(self) % {{{
+			if strncmp(self.descriptor,'distributed_',12),
+				distributed=1;
+			else
+				distributed=0;
+			end
+		end % }}}
 	end
     methods (Static)
         function []=dakota_write(fidi,dvar) % {{{
+			% collect only the variables of the appropriate class
+			hbu=struc_class(dvar,'histogram_bin_uncertain');
 
-%  collect only the variables of the appropriate class
-
-            hbu=struc_class(dvar,'histogram_bin_uncertain');
-
-%  write variables
-
+			% write variables
             vlist_write(fidi,'histogram_bin_uncertain','hbu',hbu);
         end % }}}
Index: issm/trunk/src/m/classes/qmu/histogram_bin_uncertain.py
===================================================================
--- issm/trunk/src/m/classes/qmu/histogram_bin_uncertain.py	(revision 25836)
+++ issm/trunk/src/m/classes/qmu/histogram_bin_uncertain.py	(revision 25836)
@@ -0,0 +1,206 @@
+import numpy as np
+
+from MatlabArray import string_dim
+
+
+class histogram_bin_uncertain(object):
+    '''
+    HISTOGRAM_BIN_UNCERTAIN class definition
+
+    Usage:
+        [hbu] = histogram_bin_uncertain(
+            'descriptor', descriptor,
+            'pairs_per_variable', pairs_per_variable,
+            'abscissas', abscissas,
+            'counts', counts
+            )
+
+        where the required args are:
+            descriptor          (char, description, '')
+            pairs_per_variable  (double list, [])
+            abscissas           (double list, [])
+            counts              (int list, [])
+
+    NOTE: A call to the constructor with zero arguments will return a default 
+    instance; one argument of the class copies the instance; three or more 
+    arguments constructs a new instance from the arguments.
+    '''
+
+    def __init__(self): #{{{
+        self.descriptor = ''
+        self.pairs_per_variable = []
+        self.abscissas = []
+        self.counts = []
+    #}}}
+
+    @staticmethod
+    def histogram_bin_uncertain(*args): #{{{
+        nargin = len(args)
+
+        # create a default object
+        if nargin == 0:
+            return histogram_bin_uncertain()
+
+        # copy the object
+        elif nargin == 1:
+            if isinstance(args[0], histogram_bin_uncertain):
+                hbu = args[0]
+            else:
+                raise Exception("Object {} is a {} class object, not 'histogram_bin_uncertain'.".format(str(args[0]), str(type(args[0]))))
+
+        elif nargin == 2 or nargin == 3:
+            raise Exception("Construction of 'histogram_bin_uncertain' class object requires at least {} inputs.".format(4))
+
+        # create the object from the input
+        elif nargin == 4:
+            hbu = histogram_bin_uncertain()
+
+            #recover options:
+            options = pairoptions(*args)
+
+            #initialize fields:
+            hbu.descriptor          = options.getfieldvalue('descriptor')
+            hbu.pairs_per_variable  = options.getfieldvalue('pairs_per_variable')
+            hbu.abscissas           = options.getfieldvalue('abscissas')
+            hbu.counts              = options.getfieldvalue('counts')
+
+        else:
+            raise Exception("Construction of histogram_bin_uncertain class object requires either (1) no arguments, (2) a histogram_bin_uncertain instance to copy from, or (3) a descriptor and pairs per variable, abscissas, and counts lists")
+
+    @staticmethod
+    def __repr__(hbu): #{{{
+        s = ""
+        for i in range(len(hbu)):
+            s += "class {} object {} = \n".format(hbu.__class__.__name__, string_dim(hbu, i))
+        s = "{}\n{}".format(s, fielddisplay(self, 'descriptor', 'name tag'))
+        s = "{}\n{}".format(s, fielddisplay(self, 'pairs_per_variable', 'pairs per variable'))
+        s = "{}\n{}".format(s, fielddisplay(self, 'abscissas', 'abscissas'))
+        s = "{}\n{}".format(s, fielddisplay(self, 'counts', 'counts'))
+
+        return s
+    #}}}
+
+    def checkconsistency(self, md, solution, analyses): #{{{
+        return
+    #}}}
+
+    #virtual functions needed by qmu processing algorithms
+    #implemented:
+
+    @staticmethod
+    def prop_desc(hbu, dstr): #{{{
+        desc = ['' for i in range(np.size(hbu))]
+        for i in range(np.size(hbu)):
+            if hbu[i].descriptor != '' or type(hbu[i].descriptor) != str:
+                desc[i] = str(hbu[i].descriptor)
+            elif dstr != '':
+                desc[i] = str(dstr) + str(string_dim(hbu, i, 'vector'))
+            else:
+                desc[i] = 'hbu' + str(string_dim(hbu, i, 'vector'))
+
+        desc = allempty(desc)
+
+        return desc
+    #}}}
+
+    @staticmethod
+    def prop_mean(hbu): #{{{
+        mean = np.zeros(np.size(hbu))
+        for i in range(np.size(hbu)):
+            mean[i] = hbu[i].mean
+        return mean
+    #}}}
+
+    @staticmethod
+    def prop_stddev(hbu): #{{{
+        stddev = np.zeros(np.size(hbu))
+        for i in range(np.size(hbu)):
+            stddev[i] = hbu[i].stddev
+        return stddev
+    #}}}
+
+    @staticmethod
+    def prop_lower(hbu): #{{{
+        lower = []
+        return
+    #}}}
+
+    @staticmethod
+    def prop_upper(hbu): #{{{
+        upper = []
+        return upper
+    #}}}
+
+    #default
+    @staticmethod
+    def prop_abscissas(hbu): #{{{
+        abscissas = []
+        for i in range(len(hbu)):
+            abscissas.extend(hbu[i].abscissas)
+        abscissas = allequal(abscissas, -np.inf)
+        return abscissas
+    #}}}
+
+    @staticmethod
+    def prop_pairs_per_variable(hbu): #{{{
+        pairs_per_variable = np.zeros((1, len(hbu)))
+        for i in range(len(hbu)):
+            pairs_per_variable[i] = hbu[i].pairs_per_variable
+        abscissas = allequal(pairs_per_variable, -np.inf)
+        return pairs_per_variable
+    #}}}
+
+    @staticmethod
+    def prop_counts(hbu): #{{{
+        counts = []
+        for i in range(len(hbu)):
+            counts.extend(hbu[i].counts)
+        counts = allequal(counts, -np.inf)
+        return counts
+    #}}}
+
+    @staticmethod
+    def prop_initpt(hbu): #{{{
+        initpt = []
+        return initpt
+    #}}}
+
+    @staticmethod
+    def prop_initst(hbu): #{{{
+        inist = []
+        return inist
+    #}}}
+
+    @staticmethod
+    def prop_stype(hbu): #{{{
+        stype = []
+        return stype
+    #}}}
+
+    @staticmethod
+    def prop_scale(hbu): #{{{
+        scale = []
+        return scale
+    #}}}
+
+    #new methods:
+    def isscaled(self): #{{{
+        if strncmp(self.descriptor, 'scaled_', 7):
+            return True
+        else:
+            return False
+    #}}}
+
+    @staticmethod
+    def dakota_write(fidi, dvar):
+        # possible namespace pollution, the above import seems not to work
+        from vlist_write import vlist_write
+        # collect only the variables of the appropriate class
+        hbu = deepcopy(dvar)
+        fields = fieldnames(hbu)
+        for field in fields:
+            if getattr(hbu, field)[0].__class__.__name__ != 'histogram_bin_uncertain':
+                delattr(hbu, field)
+        if len(hbu) > 0:
+            vlist_write(fidi, 'histogram_bin_uncertain', 'hbu', hbu)
+    #}}}
Index: issm/trunk/src/m/classes/qmu/linear_inequality_constraint.py
===================================================================
--- issm/trunk/src/m/classes/qmu/linear_inequality_constraint.py	(revision 24686)
+++ issm/trunk/src/m/classes/qmu/linear_inequality_constraint.py	(revision 25836)
@@ -13,5 +13,5 @@
   where the required args are:
     matrix        (double row, variable coefficients, float('NaN'))
-    lower         (double vector, lower bounds, -np.Inf)
+    lower         (double vector, lower bounds, -np.inf)
     upper         (double vector, upper bounds, 0.)
   and the optional args and defaults are:
@@ -25,5 +25,5 @@
     def __init__(self):
         self.matrix = np.array([[float('NaN')]])
-        self.lower = -np.Inf
+        self.lower = -np.inf
         self.upper = 0.
         self.scale_type = 'none'
@@ -131,5 +131,5 @@
             lower[i] = lic[i].lower
 
-        lower = allequal(lower, -np.Inf)
+        lower = allequal(lower, -np.inf)
 
         return lower
Index: issm/trunk/src/m/classes/qmu/normal_uncertain.m
===================================================================
--- issm/trunk/src/m/classes/qmu/normal_uncertain.m	(revision 24686)
+++ issm/trunk/src/m/classes/qmu/normal_uncertain.m	(revision 25836)
@@ -1,218 +1,186 @@
+%NORMAL_UNCERTAIN class definition
 %
-%  definition for the normal_uncertain class.
+%   Usage:
+%      nuv=normal_uncertain('descriptor',descriptor,'mean',mean,'stddev',stddev,'partition',partition);
+%      where nuv is the normal_uncertain object returned by the constructor, mean and stddev are self
+%      explanatory.  partition is the partition vector for distributed variables. Can be a partition
+%      vector over elements or vertices.
 %
-%  [nuv]=normal_uncertain(varargin)
+%   Example:
+%      md.qmu.variables.rheology=normal_uncertain('descriptor','RheologyBBar','mean',1,'stddev',.05);
+%      md.qmu.variables.rheology=normal_uncertain('descriptor','scaled_RheologyBBar','mean',1,'stddev',.05,'partition',vpartition);
 %
-%  where the required varargin are:
-%    descriptor    (char, description, '')
-%    mean          (double, mean, NaN)
-%    stddev        (double, standard deviation, NaN)
-%  and the optional varargin and defaults are:
-%    lower         (double, lower bound, -Inf)
-%    upper         (double, upper bound,  Inf)
-%
-%  note that zero arguments constructs a default instance; one
-%  argument of the class copies the instance; and three or more
-%  arguments constructs a new instance from the arguments.
-%
-%  "Copyright 2009, by the California Institute of Technology.
-%  ALL RIGHTS RESERVED. United States Government Sponsorship
-%  acknowledged. Any commercial use must be negotiated with
-%  the Office of Technology Transfer at the California Institute
-%  of Technology.  (J. Schiermeier, NTR 47078)
-%
-%  This software may be subject to U.S. export control laws.
-%  By accepting this  software, the user agrees to comply with
-%  all applicable U.S. export laws and regulations. User has the
-%  responsibility to obtain export licenses, or other export
-%  authority as may be required before exporting such information
-%  to foreign countries or providing access to foreign persons."
-%
+
 classdef normal_uncertain
-    properties
-        descriptor='';
-        mean      = NaN;
-        stddev    = NaN;
-        lower     =-Inf;
-        upper     = Inf;
-    end
+	properties
+		descriptor	= '';
+		mean		= NaN;
+		stddev		= NaN;
+		partition	= [];
+		nsteps		= 0;
+	end
+	methods
+		function self=normal_uncertain(varargin) %constructor {{{
 
-    methods
-        function [nuv]=normal_uncertain(varargin)
+			%recover options:
+			options=pairoptions(varargin{:});
 
-            switch nargin
+			%initialize fields:
+			self.descriptor=getfieldvalue(options,'descriptor');
+			self.mean=getfieldvalue(options,'mean');
+			self.stddev=getfieldvalue(options,'stddev');
 
-%  create a default object
+			%if the variable is scaled,  a partition vector should have been 
+			%supplied, and that partition vector should have as many partitions 
+			%as the mean and stddev vectors:
+			if self.isscaled(),
+				self.partition=getfieldvalue(options,'partition');
+				self.nsteps=getfieldvalue(options,'nsteps',1);
+				npart=qmupart2npart(self.partition);
+				if npart~=size(self.mean,1),
+					error(['normal_uncertain constructor: for the scaled variable ' self.descriptor ' the row size of the mean field should be identical to the number of partitions']);
+				end
+				if npart~=size(self.stddev,1),
+					error(['normal_uncertain constructor: for the scaled variable ' self.descriptor ' the row size of the stddev field should be identical to the number of partitions']);
+				end
+				if self.nsteps~=size(self.mean,2),
+					error(['normal_uncertain constructor: for the scaled variable ' self.descriptor ' the col size of the mean field should be identical to the number of time steps']);
+				end
+				if self.nsteps~=size(self.stddev,2),
+					error(['normal_uncertain constructor: for the scaled variable ' self.descriptor ' the col size of the stddev field should be identical to the number of time steps']);
+				end
 
-                case 0
+			end
 
-%  copy the object
+		end %}}}
+		function disp(self) % {{{
+			disp(sprintf('   normal uncertain variable: '));
+			fielddisplay(self,'descriptor','name tag');
+			fielddisplay(self,'mean','pdf mean');
+			fielddisplay(self,'stddev','pdf standard deviation');
+			if ~isempty(self.partition),
+				fielddisplay(self,'partition','partition vector defining where sampling will occur');
+			end
+			fielddisplay(self,'nsteps','number of time steps');
+		end
+		%}}}
+		function md=checkconsistency(self,md,solution,analyses) % {{{
 
-                case 1
-                    if isa(varargin{1},'normal_uncertain')
-                        nuv=varargin{1};
-                    else
-                        error('Object ''%s'' is a ''%s'' class object, not ''%s''.',...
-                            inputname(1),class(varargin{1}),'normal_uncertain');
-                    end
+			md = checkfield(md,'field',self.mean,'fieldname','normal_uncertain.mean','NaN',1,'Inf',1,'>=',0);
+			md = checkfield(md,'field',self.stddev,'fieldname','normal_uncertain.stddev','NaN',1,'Inf',1,'>=',0);
+			if self.isscaled(),
+				if isempty(self.partition),
+					error('normal_uncertain is a scaled variable, but it''s missing a partition vector');
+				end
+				%better have a partition vector that has as many partitions as stddev's size:
+				if size(self.stddev,1)~=partition_npart(self.partition),
+					error('normal_uncertain error message: row size of stddev and partition size should be identical');
+				end
+				if size(self.mean,1)~=partition_npart(self.partition),
+					error('normal_uncertain error message: row size of mean and partition size should be identical');
+				end
+				%we need as steps in stddev and mean as there are time steps: 
+				if size(self.stddev,2)~=self.nsteps,
+					error('normal_uncertain error message: col size of stddev and number of time steps should be identical');
+				end
+				if size(self.mean,2)~=self.nsteps,
+					error('normal_uncertain error message: col size of mean and number of time steps should be identical');
+				end
 
-%  not enough arguments
-
-                case 2
-                    error('Construction of ''%s'' class object requires at least %d inputs.',...
-                        'normal_uncertain',3)
-
-%  create the object from the input
-
-                otherwise
-                    asizec=num2cell(array_size(varargin{1:min(nargin,5)}));
-                    nuv(asizec{:})=normal_uncertain;
-                    clear asizec
-
-                    if ischar(varargin{1})
-                        varargin{1}=cellstr(varargin{1});
-                    end
-                    for i=1:numel(nuv)
-                        if (numel(varargin{1}) > 1)
-                            nuv(i).descriptor=varargin{1}{i};
-                        else
-                            if numel(nuv)==1,
-								nuv(i).descriptor=char(varargin{1});
-							else
-								nuv(i).descriptor=[char(varargin{1}) num2str(i)];
-							end
-                        end
-                        if (numel(varargin{2}) > 1)
-                            nuv(i).mean      =varargin{2}(i);
-                        else
-                            nuv(i).mean      =varargin{2};
-                        end
-                        if (numel(varargin{3}) > 1)
-                            nuv(i).stddev    =varargin{3}(i);
-                        else
-                            nuv(i).stddev    =varargin{3};
-                        end
-                    end
-
-                    if (nargin >= 4)
-                        for i=1:numel(nuv)
-                            if (numel(varargin{4}) > 1)
-                                nuv(i).lower     =varargin{4}(i);
-                            else
-                                nuv(i).lower     =varargin{4};
-                            end
-                        end
-                        if (nargin >= 5)
-                            for i=1:numel(nuv)
-                                if (numel(varargin{5}) > 1)
-                                    nuv(i).upper     =varargin{5}(i);
-                                else
-                                    nuv(i).upper     =varargin{5};
-                                end
-                            end
-                            if (nargin > 5)
-                                warning('normal_uncertain:extra_arg',...
-                                    'Extra arguments for object of class ''%s''.',...
-                                    class(nuv));
-                            end
-                        end
-                    end
-            end
-
-        end
-
-        function []=disp(nuv)
-
-%  display the object
-
-            disp(sprintf('\n'));
-            for i=1:numel(nuv)
-                disp(sprintf('class ''%s'' object ''%s%s'' = \n',...
-                    class(nuv),inputname(1),string_dim(nuv,i)));
-                disp(sprintf('    descriptor: ''%s'''  ,nuv(i).descriptor));
-                disp(sprintf('          mean: %g'      ,nuv(i).mean));
-                disp(sprintf('        stddev: %g'      ,nuv(i).stddev));
-                disp(sprintf('         lower: %g'      ,nuv(i).lower));
-                disp(sprintf('         upper: %g\n'    ,nuv(i).upper));
-            end
-
-        end
-
-        function [desc]  =prop_desc(nuv,dstr)
-            desc=cell(1,numel(nuv));
-            for i=1:numel(nuv)
-                if ~isempty(nuv(i).descriptor)
-                    desc(i)=cellstr(nuv(i).descriptor);
-                elseif ~isempty(inputname(1))
-                    desc(i)=cellstr([inputname(1) string_dim(nuv,i,'vector')]);
-                elseif exist('dstr','var')
-                    desc(i)=cellstr([dstr         string_dim(nuv,i,'vector')]);
-                else
-                    desc(i)=cellstr(['nuv'        string_dim(nuv,i,'vector')]);
-                end
-            end
-            desc=allempty(desc);
-        end
-        function [initpt]=prop_initpt(nuv)
-            initpt=[];
-        end
-        function [lower] =prop_lower(nuv)
-            lower=zeros(1,numel(nuv));
-            for i=1:numel(nuv)
-                lower(i)=nuv(i).lower;
-            end
-            lower=allequal(lower,-Inf);
-        end
-        function [upper] =prop_upper(nuv)
-            upper=zeros(1,numel(nuv));
-            for i=1:numel(nuv)
-                upper(i)=nuv(i).upper;
-            end
-            upper=allequal(upper, Inf);
-        end
-        function [mean]  =prop_mean(nuv)
-            mean=zeros(1,numel(nuv));
-            for i=1:numel(nuv)
-                mean(i)=nuv(i).mean;
-            end
-        end
-        function [stddev]=prop_stddev(nuv)
-            stddev=zeros(1,numel(nuv));
-            for i=1:numel(nuv)
-                stddev(i)=nuv(i).stddev;
-            end
-        end
-        function [initst]=prop_initst(nuv)
-            initst=[];
-        end
-        function [stype] =prop_stype(nuv)
-            stype={};
-        end
-        function [scale] =prop_scale(nuv)
-            scale=[];
-        end
-		function [abscissas] =prop_abscissas(hbu) % {{{
-            abscissas=[]; 
-        end % }}}
-        function [counts] =prop_counts(hbu) % {{{
-            counts=[]; 
-        end % }}}
-        function [pairs_per_variable] =prop_pairs_per_variable(hbu) % {{{
+				md = checkfield(md,'field',self.partition,'fieldname','normal_uncertain.partition','NaN',1,'Inf',1,'>=',-1,'numel',[md.mesh.numberofvertices,md.mesh.numberofelements]);
+				if size(self.partition,2)>1,
+					error('normal_uncertain error message: partition should be a column vector');
+				end
+				partcheck=unique(self.partition);
+				partmin=min(partcheck);
+				partmax=max(partcheck);
+				if partmax<-1,
+					error('normal_uncertain error message: partition vector''s min value should be -1 (for no partition), or start at 0');
+				end
+				nmax=max(md.mesh.numberofelements,md.mesh.numberofvertices);
+				if partmax>nmax,
+					error('normal_uncertain error message: partition vector''s values cannot go over the number of vertices or elements');
+				end
+			end
+		end % }}}
+		%virtual functions needed by qmu processing algorithms:
+		%implemented:
+		function [desc]=prop_desc(nuv,dstr) % {{{
+			desc=cell(1,numel(nuv));
+			for i=1:numel(nuv)
+				if ~isempty(nuv(i).descriptor)
+					desc(i)=cellstr(nuv(i).descriptor);
+				elseif ~isempty(inputname(1))
+					desc(i)=cellstr([inputname(1) string_dim(nuv,i,'vector')]);
+				elseif exist('dstr','var')
+					desc(i)=cellstr([dstr         string_dim(nuv,i,'vector')]);
+				else
+					desc(i)=cellstr(['nuv'        string_dim(nuv,i,'vector')]);
+				end
+			end
+			desc=allempty(desc);
+		end %}}}
+		function [mean]=prop_mean(nuv) % {{{
+			mean=zeros(1,numel(nuv));
+			for i=1:numel(nuv)
+				mean(i)=nuv(i).mean;
+			end
+		end % }}}
+		function [stddev]=prop_stddev(nuv) % {{{
+			stddev=zeros(1,numel(nuv));
+			for i=1:numel(nuv)
+				stddev(i)=nuv(i).stddev;
+			end
+		end % }}}
+		function [lower]=prop_lower(nuv) % {{{
+			lower=[];
+		end % }}}
+		function [upper]=prop_upper(nuv) % {{{
+			upper=[];
+		end % }}}
+		function [abscissas]=prop_abscissas(hbu) % {{{
+			abscissas=[];
+		end % }}}
+		function [counts]=prop_counts(hbu) % {{{
+			counts=[];
+		end % }}}
+		function [pairs_per_variable]=prop_pairs_per_variable(hbu) % {{{
 			pairs_per_variable=[];
-        end % }}}
-
-    end
-
-    methods (Static)
-        function []=dakota_write(fidi,dvar)
-
-%  collect only the variables of the appropriate class
-
-            nuv=struc_class(dvar,'normal_uncertain');
-
-%  write variables
-
-            vlist_write(fidi,'normal_uncertain','nuv',nuv);
-        end
-    end
+		end % }}}
+		function [initpt]=prop_initpt(nuv) % {{{
+			initpt=[];
+		end % }}}
+		function [initst]=prop_initst(nuv) % {{{
+			initst=[];
+		end % }}}
+		function [stype]=prop_stype(nuv) % {{{
+			stype={};
+		end % }}}
+		function [scale]=prop_scale(nuv) % {{{
+			scale=[];
+		end % }}}
+		%new methods:
+		function distributed=isdistributed(self) % {{{
+			if strncmp(self.descriptor,'distributed_',12),
+				distributed=1;
+			else
+				distributed=0;
+			end
+		end % }}}
+		function scaled=isscaled(self) % {{{
+			if strncmp(self.descriptor,'scaled_',7),
+				scaled=1;
+			else
+				scaled=0;
+			end
+		end % }}}
+	end
+	methods (Static)
+		function []=dakota_write(fidi,dvar) % {{{
+			%  collect only the variables of the appropriate class
+			nuv=struc_class(dvar,'normal_uncertain');
+			%  write variables
+			vlist_write(fidi,'normal_uncertain','nuv',nuv);
+		end % }}}
+	end
 end
Index: issm/trunk/src/m/classes/qmu/normal_uncertain.py
===================================================================
--- issm/trunk/src/m/classes/qmu/normal_uncertain.py	(revision 24686)
+++ issm/trunk/src/m/classes/qmu/normal_uncertain.py	(revision 25836)
@@ -1,34 +1,52 @@
 import numpy as np
+
 from MatlabArray import *
+from MatlabFuncs import *
+from fielddisplay import fielddisplay
+from pairoptions import pairoptions
+from partition_npart import *
+from qmupart2npart import qmupart2npart
 
 
 class normal_uncertain(object):
-    '''
-  definition for the normal_uncertain class.
-
-  [nuv] = normal_uncertain.normal_uncertain(args)
-   nuv = normal_uncertain()
-
-  where the required args are:
-    descriptor    (str, description, '')
-    mean          (float, mean, float('NaN'))
-    stddev        (float, standard deviation, float('NaN'))
-  and the optional args and defaults are:
-    lower         (float, lower bound, -np.Inf)
-    upper         (float, upper bound, np.Inf)
-
-  note that zero arguments constructs a default instance, one
-  argument of the class copies the instance, and three or more
-  arguments constructs a new instance from the arguments.
-'''
-    def __init__(self):
+    """NORMAL_UNCERTAIN class definition
+
+    Usage:
+        [nuv] = normal_uncertain(
+            'descriptor', descriptor,
+            'mean', mean,
+            'stddev', stddev,
+            'partition', partition
+            )
+
+        where nuv is the normal_uncertain object returned by the constructor, 
+        mean and stddev are self explanatory, and partition is the partition 
+        vector for distributed variables. Can be a partition vector over 
+        elements or vertices.
+
+    Example:
+        md.qmu.variables.rheology=normal_uncertain(
+            'descriptor','RheologyBBar',
+            'mean',1,
+            'stddev',.05
+            )
+        md.qmu.variables.rheology=normal_uncertain(
+            'descriptor','scaled_RheologyBBar',
+            'mean',1,
+            'stddev',.05,
+            'partition',vpartition
+            )
+    """
+
+    def __init__(self): #{{{
         self.descriptor = ''
-        self.mean = float('NaN')
-        self.stddev = float('NaN')
-        self.lower = -np.Inf
-        self.upper = np.Inf
-
-    @staticmethod
-    def normal_uncertain(*args):
+        self.mean       = np.nan
+        self.stddev     = np.nan
+        self.partition  = []
+        self.nsteps     = 0
+    #}}}
+
+    @staticmethod
+    def normal_uncertain(*args): #{{{
         nargin = len(args)
 
@@ -42,51 +60,90 @@
                 nuv = args[0]
             else:
-                raise RuntimeError('Object ' + str(args[0]) + ' is a ' + str(type(args[0])) + ' class object, not "normal_uncertain".')
-
-        # not enough arguments
-        elif nargin == 2:
-            raise RuntimeError('Construction of "normal_uncertain" class object requires at least 3 inputs.')
-
-    # create the object from the input
-        else:
-            # lines differ here in other classes / tests; see asizec problem in notes
+                raise Exception('Object ' + str(args[0]) + ' is a ' + str(type(args[0])) + ' class object, not "normal_uncertain".')
+
+        # create the object from the input
+        else:
             nuv = normal_uncertain()
-            nuv.descriptor = str(args[0])
-            nuv.mean = args[1]
-            nuv.stddev = args[2]
-            if nargin >= 4:
-                nuv.lower = args[3]
-            if nargin >= 5:
-                nuv.upper = args[4]
-            if nargin > 5:
-                print('WARNING: normal_uncertain:extra_arg: Extra arguments for object of class ' + str(type(nuv)) + '.')
-
-        return [nuv]
-
-    def __repr__(self):
-        # display an individual object
-        string = '\n'
-        string += 'class "normal_uncertain" object = \n'
-        string += '    descriptor: ' + str(self.descriptor) + '\n'
-        string += '          mean: ' + str(self.mean) + '\n'
-        string += '        stddev: ' + str(self.stddev) + '\n'
-        string += '         lower: ' + str(self.lower) + '\n'
-        string += '         upper: ' + str(self.upper) + '\n'
+
+            #recover options:
+            options = pairoptions(*args)
+
+            #initialize fields:
+            nuv.descriptor = options.getfieldvalue('descriptor')
+            nuv.mean       = options.getfieldvalue('mean')
+            nuv.stddev     = options.getfieldvalue('stddev')
+
+            #if the variable is scaled, a partition vector should have been 
+            #supplied, and that partition vector should have as many partitions 
+            #as the mean and stddev vectors:
+            if nuv.isscaled():
+                nuv.partition = options.getfieldvalue('partition')
+                nuv.nsteps = options.getfieldvalue('nsteps', 1)
+                npart = qmupart2npart(nuv.partition)
+                if npart != nuv.mean.shape[0]:
+                    raise Exception("normal_uncertain constructor: for the scaled variable %s the row size of the mean field should be identical to the number of partitions" % nuv.descriptor)
+                if npart != nuv.stddev.shape[0]:
+                    raise Exception("normal_uncertain constructor: for the scaled variable %s the row size of the stddev field should be identical to the number of partitions" % nuv.descriptor)
+                if nuv.nsteps != nuv.mean.shape[1]:
+                    raise Exception("normal_uncertain constructor: for the scaled variable %s the col size of the mean field should be identical to the number of time steps" % nuv.descriptor)
+                if nuv.nsteps != nuv.stddev.shape[1]:
+                    raise Exception("normal_uncertain constructor: for the scaled variable %s the col size of the stddev field should be identical to the number of time steps" % nuv.descriptor)
+
+        return [nuv] # Always return a list, so we have something akin to a MATLAB single row matrix
+    #}}}
+
+    def __repr__(self): #{{{
+        string = '   normal uncertain variable: '
+        string = "%s\n%s" % (string, fielddisplay(self, 'descriptor', 'name tag'))
+        string = "%s\n%s" % (string, fielddisplay(self, 'mean', 'pdf mean'))
+        string = "%s\n%s" % (string, fielddisplay(self, 'stddev', 'pdf standard deviation'))
+        if self.partition != []:
+            string = "%s\n%s" % (string, fielddisplay(self, 'partition', 'partition vector defining where sampling will occur'))
+        string = "%s\n%s" % (string, fielddisplay(self, 'nsteps', 'number of time steps'))
 
         return string
-
-    # from here on, nuv is either a single, or a 1d vector of, normal_uncertain
-
-    @staticmethod
-    def prop_desc(nuv, dstr):
-        if type(nuv) not in [list, np.ndarray]:
-            if nuv.descriptor != '' or type(nuv.descriptor) != str:
-                desc = str(nuv.descriptor)
-            elif dstr != '':
-                desc = str(dstr)
-            else:
-                desc = 'nuv'
-            return desc
-
+    #}}}
+
+    def __len__(self): #{{{
+        if type(self.mean) in [list, np.ndarray]:
+            return len(self.mean)
+        else:
+            return 1
+    #}}}
+
+    def checkconsistency(self, md, solution, analyses): #{{{
+        md = checkfield(md, 'field', self.mean, 'fieldname', 'normal_uncertain.mean', 'NaN', 1, 'Inf', 1, '>=', 0)
+        md = checkfield(md, 'field', self.stddev, 'fieldname', 'normal_uncertain.stddev', 'NaN', 1, 'Inf', 1, '>=', 0)
+        if self.isscaled():
+            if self.partition == []:
+                raise Exception("normal_uncertain is a scaled variable, but it's missing a partition vector")
+            #better have a partition vector that has as many partitions as stddev's size:
+            if self.stddev.shape[0] != partition_npart(self.partititon):
+                raise Exception("normal_uncertain error message: row size of stddev and partition size should be identical")
+            if self.mean.shape[0] != partition_npart(self.partition):
+                raise Exception("normal_uncertain error message: row size of mean and partition size should be identical")
+            #we need as many steps in stddev and mean as there are in time steps
+            if self.stddev.shape[1] != self.nsteps:
+                raise Exception("normal_uncertain error message: col size of stddev and partition size should be identical")
+            if self.mean.shape[1] != self.nsteps:
+                raise Exception("normal_uncertain error message: col size of mean and partition size should be identical")
+            md = checkfield(md, 'field', self.partition, 'fieldname', 'normal_uncertain.partition', 'NaN', 1, 'Inf', 1, '>=', -1, 'numel', [md.mesh.numberofvertices, md.mesh.numberofvertices])
+            if self.partition.shape[1] > 1:
+                raise Exception("normal_uncertain error message: partition should be a column vector")
+            partcheck = np.unique(self.partition)
+            partmin = min(partcheck)
+            partmax = max(partcheck)
+            if partmax < -1:
+                raise Exception("normal_uncertain error message: partition vector's min value should be -1 (for no partition), or start at 0")
+            nmax = max(md.mesh.numberofelements, md.mesh.numberofvertices)
+            if partmax > nmax:
+                raise Exception("normal_uncertain error message: partition vector's values cannot go over the number of vertices or elements")
+    #}}}
+
+    #virtual functions needed by qmu processing algorithms
+    #implemented:
+
+    @staticmethod
+    def prop_desc(nuv, dstr): #{{{
         desc = ['' for i in range(np.size(nuv))]
         for i in range(np.size(nuv)):
@@ -101,79 +158,103 @@
 
         return desc
-
-    @staticmethod
-    def prop_initpt(nuv):
-        initpt = []
-        return initpt
-
-    @staticmethod
-    def prop_lower(nuv):
-        if type(nuv) not in [list, np.ndarray]:
-            return nuv.lower
-
-        lower = np.zeros(np.size(nuv))
-        for i in range(np.size(nuv)):
-            lower[i] = nuv[i].lower
-
-        lower = allequal(lower, -np.inf)
-
-        return lower
-
-    @staticmethod
-    def prop_upper(nuv):
-        if type(nuv) not in [list, np.ndarray]:
-            return nuv.upper
-
-        upper = np.zeros(np.size(nuv))
-        for i in range(np.size(nuv)):
-            upper[i] = nuv[i].upper
-
-        upper = allequal(upper, -np.inf)
-        return upper
-
-    @staticmethod
-    def prop_mean(nuv):
-        if type(nuv) not in [list, np.ndarray]:
-            return nuv.mean
-
+    #}}}
+
+    @staticmethod
+    def prop_mean(nuv): #{{{
         mean = np.zeros(np.size(nuv))
         for i in range(np.size(nuv)):
             mean[i] = nuv[i].mean
-
         return mean
-
-    @staticmethod
-    def prop_stddev(nuv):
-        if type(nuv) not in [list, np.ndarray]:
-            return nuv.stddev
-
+    #}}}
+
+    @staticmethod
+    def prop_stddev(nuv): #{{{
         stddev = np.zeros(np.size(nuv))
         for i in range(np.size(nuv)):
             stddev[i] = nuv[i].stddev
-
         return stddev
-
-    @staticmethod
-    def prop_initst(nuv):
-        initst = []
-        return initst
-
-    @staticmethod
-    def prop_stype(nuv):
+    #}}}
+
+    @staticmethod
+    def prop_lower(nuv): #{{{
+        lower = []
+        return lower
+    #}}}
+
+    @staticmethod
+    def prop_upper(nuv): #{{{
+        upper = []
+        return upper
+    #}}}
+
+    #default
+    @staticmethod
+    def prop_abscissas(hbu): #{{{
+        abscissas = []
+        return abscissas
+    #}}}
+
+    @staticmethod
+    def prop_pairs_per_variable(hbu): #{{{
+        pairs_per_variable = []
+        return pairs_per_variable
+    #}}}
+
+    @staticmethod
+    def prop_counts(hbu): #{{{
+        counts = []
+        return counts
+    #}}}
+    @staticmethod
+    def prop_initpt(nuv): #{{{
+        initpt = []
+        return initpt
+    #}}}
+
+    @staticmethod
+    def prop_initst(nuv): #{{{
+        inist = []
+        return inist
+    #}}}
+
+    @staticmethod
+    def prop_stype(nuv): #{{{
         stype = []
         return stype
-
-    @staticmethod
-    def prop_scale(nuv):
+    #}}}
+
+    @staticmethod
+    def prop_scale(nuv): #{{{
         scale = []
         return scale
+    #}}}
+
+    #new methods:
+    def isdistributed(self): #{{{
+        if strncmp(self.descriptor, 'distributed_', 12):
+            return True
+        else:
+            return False
+    #}}}
+    
+    def isscaled(self): #{{{
+        if strncmp(self.descriptor, 'scaled_', 7):
+            return True
+        else:
+            return False
+    #}}}
 
     @staticmethod
     def dakota_write(fidi, dvar):
+        # possible namespace pollution, the above import seems not to work
+        from vlist_write import vlist_write
         # collect only the variables of the appropriate class
-        nuv = [struc_class(i, 'normal_uncertain', 'nuv') for i in dvar]
-
-    # possible namespace pollution, the above import seems not to work
-        from vlist_write import vlist_write
-    # write variables
-        vlist_write(fidi, 'normal_uncertain', 'nuv', nuv)
+        nuv = deepcopy(dvar)
+        fields = fieldnames(nuv)
+        for field in fields:
+            if getattr(nuv, field)[0].__class__.__name__ != 'normal_uncertain':
+                delattr(nuv, field)
+        if len(nuv) > 0:
+            vlist_write(fidi, 'normal_uncertain', 'nuv', nuv)
+    #}}}
+
Index: issm/trunk/src/m/classes/qmu/partition_npart.m
===================================================================
--- issm/trunk/src/m/classes/qmu/partition_npart.m	(revision 25836)
+++ issm/trunk/src/m/classes/qmu/partition_npart.m	(revision 25836)
@@ -0,0 +1,13 @@
+function npart=partition_npart(vector)
+
+	%vector could be on vertices or elements, and will have a small amount of possible integer 
+	%values: 
+	uvec=unique(vector);
+	uvec(uvec==-1)=[];
+
+	%ok, so now we should have a vector from 0 to npart-1:
+	npart=max(uvec)+1;
+	if npart~=length(uvec),
+		error('partition vector should be in the range 0 to numberofpartitions, with -1 values for vertices or elements not belonging to any partition');
+	end
+
Index: issm/trunk/src/m/classes/qmu/partition_npart.py
===================================================================
--- issm/trunk/src/m/classes/qmu/partition_npart.py	(revision 25836)
+++ issm/trunk/src/m/classes/qmu/partition_npart.py	(revision 25836)
@@ -0,0 +1,13 @@
+import numpy as np
+
+def partition_npart(vector):
+    #vector could be on vertices or elements, and will have a small amount of possible integer
+    #values:
+    uvec = np.unique(vector)
+    uvec = np.delete(uvec, np.where(uvec == -1))
+
+    #ok, so now we should have a vector from 0 to npart-1:
+    npart = max(uvec) + 1
+    if npart != len(uvec):
+        raise RuntimeError('partition vector should be in the range 0 to numberofpartitions, with -1 values for vertices or elements not belonging to any partition')
+    return npart
Index: issm/trunk/src/m/classes/qmu/response_function.m
===================================================================
--- issm/trunk/src/m/classes/qmu/response_function.m	(revision 24686)
+++ issm/trunk/src/m/classes/qmu/response_function.m	(revision 25836)
@@ -1,32 +1,15 @@
+%RESPONSE_FUNCTION class definition
 %
-%  definition for the response_function class.
-%
-%  [rf]=response_function(varargin)
-%
-%  where the required varargin are:
-%    descriptor    (char, description, '')
-%  and the optional varargin and defaults are:
-%    respl         (double vector, response levels, [])
-%    probl         (double vector, probability levels, [])
-%    rell          (double vector, reliability levels, [])
-%    grell         (double vector, gen. reliability levels, [])
-%
-%  note that zero arguments constructs a default instance; one
-%  argument of the class copies the instance; and one or more
-%  arguments constructs a new instance from the arguments.
-%
-%  "Copyright 2009, by the California Institute of Technology.
-%  ALL RIGHTS RESERVED. United States Government Sponsorship
-%  acknowledged. Any commercial use must be negotiated with
-%  the Office of Technology Transfer at the California Institute
-%  of Technology.  (J. Schiermeier, NTR 47078)
-%
-%  This software may be subject to U.S. export control laws.
-%  By accepting this  software, the user agrees to comply with
-%  all applicable U.S. export laws and regulations. User has the
-%  responsibility to obtain export licenses, or other export
-%  authority as may be required before exporting such information
-%  to foreign countries or providing access to foreign persons."
-%
+%   Usage:
+%      rf=response_function('descriptor',descriptor,'response_levels',respl,...
+%           'probability_levels',probl,'reliability_levels',rell,general_reliability_levels',grell,...
+%           'partition',partition);
+%      where rf is the response function object returned by the constructor. All options except the 
+%      descriptor are optional. A partition can be provided for scaled variables. 
+% 
+%   Example:
+%      md.qmu.responses.maxvel=response_function('descriptor','MaxVel','response_levels',[0],...
+%                              'probl',[0.0001 0.001 0.01 0.25 0.5 0.75 0.99 0.999 0.9999]');
+
 classdef response_function
     properties
@@ -36,69 +19,29 @@
         rell      =[];
         grell     =[];
+        partition = [];
     end
+    methods
+		function self=response_function(varargin) %constructor {{{
 
-    methods
-        function [rf]=response_function(varargin)
+			%recover options: 
+			options = pairoptions(varargin{:});
 
-            switch nargin
-
-					%  create a default object
-                case 0
-
-						 %  copy the object or create the object from the input
-                otherwise
-                    if  (nargin == 1) && isa(varargin{1},'response_function')
-                        rf=varargin{1};
-                    else
-                        asizec=num2cell(array_size(varargin{1:min(nargin,1)}));
-                        rf(asizec{:})=response_function;
-                        clear asizec
-
-                        if ischar(varargin{1})
-                            varargin{1}=cellstr(varargin{1});
-                        end
-                        for i=1:numel(rf)
-                            if (numel(varargin{1}) > 1)
-                                rf(i).descriptor=varargin{1}{i};
-                            else
-                                rf(i).descriptor=[char(varargin{1}) string_dim(rf,i,'vector')];
-                            end
-                        end
-
-                        if (nargin >= 2)
-                            for i=1:numel(rf)
-                                rf(i).respl     =varargin{2};
-                            end
-                            if (nargin >= 3)
-                                for i=1:numel(rf)
-                                    rf(i).probl     =varargin{3};
-                                end
-                                if (nargin >= 4)
-                                    for i=1:numel(rf)
-                                        rf(i).rell      =varargin{4};
-                                    end
-                                    if (nargin >= 5)
-                                        for i=1:numel(rf)
-                                            rf(i).grell     =varargin{5};
-                                        end
-
-                                        if (nargin > 5)
-                                            warning('response_function:extra_arg',...
-                                                'Extra arguments for object of class ''%s''.',...
-                                                class(rf));
-                                        end
-                                    end
-                                end
-                            end
-                        end
-                    end
-            end
-
-        end
-
-        function []=disp(rf)
-
-        %  display the object
-
+			%initialize fields: 
+			self.descriptor=getfieldvalue(options,'descriptor');
+			self.respl=getfieldvalue(options,'response_levels',[]);
+			self.probl=getfieldvalue(options,'probability_levels',...
+				[0.0001 0.001 0.01 0.25 0.5 0.75 0.99 0.999 0.9999]);
+			self.rell=getfieldvalue(options,'reliability_levels',[]);
+			self.grell=getfieldvalue(options,'general_reliability_levels',[]);
+			
+			%if the response is scaled, a partition vector should have been supplied.
+			if self.isscaled(),
+				self.partition=getfieldvalue(options,'partition');
+				npart=partition_npart(self.partition);
+			end
+		end %}}}
+        function []=disp(rf)% {{{
+            %TODO: Convert the following to fielddisplay
+            % display the object
             disp(sprintf('\n'));
             for i=1:numel(rf)
@@ -109,10 +52,14 @@
                 disp(sprintf('         probl: %s'      ,string_vec(rf(i).probl)));
                 disp(sprintf('          rell: %s'      ,string_vec(rf(i).rell)));
-                disp(sprintf('         grell: %s\n'    ,string_vec(rf(i).grell)));
+                disp(sprintf('         grell: %s'    ,string_vec(rf(i).grell)));
+                if ~isempty(rf.partition),
+					fielddisplay(rf,'partition','partition vector defining where response will be computed');
+                end
+                disp(sprintf('\n'));
             end
 
-        end
+        end % }}}
+        function [desc]  =prop_desc(rf,dstr)% {{{
 
-        function [desc]  =prop_desc(rf,dstr)
             desc=cell(1,numel(rf));
             for i=1:numel(rf)
@@ -128,24 +75,29 @@
             end
             desc=allempty(desc);
-        end
-        function [stype] =prop_stype(rf)
+        end % }}}
+        function [stype] =prop_stype(rf)% {{{
+
             stype={};
-        end
-        function [scale] =prop_scale(rf)
+        end% }}}
+        function [scale] =prop_scale(rf)% {{{
+
             scale=[];
-        end
-        function [weight]=prop_weight(rf)
+        end% }}}
+        function [weight]=prop_weight(rf) % {{{
+
             weight=[];
-        end
-        function [lower] =prop_lower(rf)
+        end% }}}
+        function [lower] =prop_lower(rf)% {{{
+
             lower=[];
-        end
-        function [upper] =prop_upper(rf)
+        end% }}}
+        function [upper] =prop_upper(rf)% {{{
+
             upper=[];
-        end
-        function [target]=prop_target(rf)
+        end % }}}
+        function [target]=prop_target(rf) % {{{
             target=[];
-        end
-        function [respl,probl,rell,grell]=prop_levels(rf)
+        end % }}}
+        function [respl,probl,rell,grell]=prop_levels(rf) % {{{
             respl=cell(1,numel(rf));
             probl=cell(1,numel(rf));
@@ -162,18 +114,23 @@
             rell =allempty(rell);
             grell=allempty(grell);
-        end
+        end % }}}
+		%new methods: 
+    	function scaled =isscaled(self) % {{{
+    		if strncmp(self.descriptor,'scaled_',7),
+    			scaled=1;
+    		else
+    			scaled=0;
+    		end
+    	end % }}}
     end
+    methods (Static)
+        function [rdesc]=dakota_write(fidi,dresp,rdesc) % {{{
 
-    methods (Static)
-        function [rdesc]=dakota_write(fidi,dresp,rdesc)
-
-			  %  collect only the responses of the appropriate class
+			%collect only the responses of the appropriate class
             rf=struc_class(dresp,'response_function');
-
-				%  write responses
-				[rdesc]=rlist_write(fidi,'response_functions','response_function',rf,rdesc);
-			end
-
-			function []=dakota_rlev_write(fidi,dresp,params)
+			%write responses
+			[rdesc]=rlist_write(fidi,'response_functions','response_function',rf,rdesc);
+		end % }}}
+		function []=dakota_rlev_write(fidi,dresp,params) % {{{
 
 				%  collect only the responses of the appropriate class
@@ -182,5 +139,5 @@
 				%  write response levels
 				rlev_write(fidi,rf,params);
-        end
+        end % }}}
     end
 end
Index: issm/trunk/src/m/classes/qmu/response_function.py
===================================================================
--- issm/trunk/src/m/classes/qmu/response_function.py	(revision 24686)
+++ issm/trunk/src/m/classes/qmu/response_function.py	(revision 25836)
@@ -1,36 +1,43 @@
 import numpy as np
+
+from fielddisplay import fielddisplay
+from MatlabFuncs import *
+from pairoptions import pairoptions
+from partition_npart import *
+from rlev_write import *
 #from rlist_write import *
-from rlev_write import *
-from MatlabArray import *
-#move this later
-from helpers import *
 
 
 class response_function(object):
     '''
-  definition for the response_function class.
-
-  [rf] = response_function.response_function(args)
-   rf = response_function()
-
-  where the required args are:
-    descriptor    (char, description, '')
-  and the optional args and defaults are:
-    respl         (double vector, response levels, [])
-    probl         (double vector, probability levels, [])
-    rell          (double vector, reliability levels, [])
-    grell         (double vector, gen. reliability levels, [])
-
-  note that zero arguments constructs a default instance, one
-  argument of the class copies the instance, and one or more
-  arguments constructs a new instance from the arguments.
-'''
-
+    RESPONSE_FUNCTION class definition
+
+        Usage:
+            rf = response_function(
+                'descriptor', descriptor,
+                'response_levels', respl,
+                'probability_levels', probl,
+                'reliability_levels',rell,
+                'general_reliability_levels', grell,
+                'partition', partition
+            )
+
+            where rf is the response function object returned by the 
+            constructor. All options except the descriptor are optional. A partition can be provided for scaled variables.
+
+        Example:
+            md.qmu.responses.maxvel = response_function(
+                'descriptor', 'MaxVel',
+                'response_levels',[0],
+                'probl', [0.0001 0.001 0.01 0.25 0.5 0.75 0.99 0.999 0.9999]
+                )
+    '''
     def __init__(self):
         self.descriptor = ''
-        self.respl = []
-        self.probl = []
-        self.rell = []
-        self.grell = []
+        self.respl      = []
+        self.probl      = []
+        self.rell       = []
+        self.grell      = []
+        self.partition  = []
 
     @staticmethod
@@ -43,61 +50,78 @@
 
         # copy the object or create the object from the input
-        else:
-            if nargin == 1 and isinstance(args[0], response_function):
+        elif nargin == 1:
+            if isinstance(args[0], response_function):
                 rf = args[0]
             else:
-                asizec = array_size(*args[0:min(nargin, 1)])
-                rf = [response_function() for i in range(asizec[0]) for j in range(asizec[1])]
-
-                for i in range(np.size(rf)):
-                    if (np.size(args[0]) > 1):
-                        rf[i].descriptor = args[0][i]
-                    else:
-                        rf[i].descriptor = str(args[0]) + string_dim(rf, i, 'vector')
-
-                if nargin >= 2:
-                    for i in range(np.size(rf)):
-                        rf[i].respl = args[1]
-
-                if nargin >= 3:
-                    for i in range(np.size(rf)):
-                        rf[i].probl = args[2]
-
-                if nargin >= 4:
-                    for i in range(np.size(rf)):
-                        rf[i].rell = args[3]
-
-                if nargin >= 5:
-                    for i in range(np.size(rf)):
-                        rf[i].grell = args[4]
-
-                if nargin > 5:
-                    print('WARNING: response_function:extra_arg: Extra arguments for object of class ' + str(type(rf)) + '.')
-
-        return rf
-
-    def __repr__(self):
-        #  display the object
-        string = '\n'
-        string += 'class "response_function" object = \n'
-        string += '    descriptor: ' + str(self.descriptor) + '\n'
-        string += '         respl: ' + str(self.respl) + '\n'
-        string += '         probl: ' + str(self.probl) + '\n'
-        string += '          rell: ' + str(self.rell) + '\n'
-        string += '         grell: ' + str(self.grell) + '\n'
+                raise RuntimeError('Object ' + str(args[0]) + ' is a ' + str(type(args[0])) + ' class object, not "response_function".')
+        else:
+            # asizec = array_size(*args[0:min(nargin, 1)])
+            # rf = [response_function() for i in range(asizec[0]) for j in range(asizec[1])]
+
+            # for i in range(np.size(rf)):
+            #     if (np.size(args[0]) > 1):
+            #         rf[i].descriptor = args[0][i]
+            #     else:
+            #         rf[i].descriptor = str(args[0]) + string_dim(rf, i, 'vector')
+
+            # if nargin >= 2:
+            #     for i in range(np.size(rf)):
+            #         rf[i].respl = args[1]
+
+            # if nargin >= 3:
+            #     for i in range(np.size(rf)):
+            #         rf[i].probl = args[2]
+
+            # if nargin >= 4:
+            #     for i in range(np.size(rf)):
+            #         rf[i].rell = args[3]
+
+            # if nargin >= 5:
+            #     for i in range(np.size(rf)):
+            #         rf[i].grell = args[4]
+
+            # if nargin > 5:
+            #     print('WARNING: response_function:extra_arg: Extra arguments for object of class ' + str(type(rf)) + '.')
+
+            rf = response_function()
+
+            #recover options:
+            options = pairoptions(*args)
+
+            #initialize fields:
+            rf.descriptor = options.getfieldvalue('descriptor')
+            rf.respl = options.getfieldvalue('response_levels', [])
+            rf.probl = options.getfieldvalue('probability_levels', [0.0001, 0.001, 0.01, 0.25, 0.5, 0.75, 0.99, 0.999, 0.9999])
+            rf.rell = options.getfieldvalue('reliability_levels', [])
+            rf.grell = options.getfieldvalue('general_reliability_levels', [])
+
+            #if the response is scaled, a partition vector should have been supplied.
+            if rf.isscaled():
+                rf.partition = options.getfieldvalue('partition')
+                npart = partition_npart(rf.partition)
+
+        return [rf] # Always return a list, so we have something akin to a MATLAB single row matrix
+
+    def __repr__(rf): #{{{
+        # display the object
+        string = 'class "response_function" object = \n'
+        string = "%s\n%s" % (string, fielddisplay(rf, 'descriptor', 'name tag'))
+        string = "%s\n%s" % (string, fielddisplay(rf, 'respl', 'response levels'))
+        string = "%s\n%s" % (string, fielddisplay(rf, 'probl', 'probability levels'))
+        string = "%s\n%s" % (string, fielddisplay(rf, 'rell', 'reliability levels'))
+        string = "%s\n%s" % (string, fielddisplay(rf, 'grell', 'general reliability levels'))
+
+        if rf.partition != []:
+            string = "%s\n%s" % (string, fielddisplay(rf, 'partition', 'partition vector defining where the response will be computed'))
 
         return string
-
-    def __len__(self):
+    #}}}
+
+    def __len__(self): #{{{
         return max(len(self.respl), len(self.probl), len(self.rell), len(self.grell))
-
-    # from here on, rf is either a single, or a 1d vector of, response_function
-
-    @staticmethod
-    def prop_desc(rf, dstr):
-        # response_function is always a vector, or should be, even with just 1
-        if type(rf) not in [list, np.ndarray]:
-            rf = [rf]
-
+    #}}}
+
+    @staticmethod
+    def prop_desc(rf, dstr): #{{{
         desc = ['' for i in range(np.size(rf))]
         for i in range(np.size(rf)):
@@ -111,46 +135,48 @@
         desc = allempty(desc)
         return desc
-
-    @staticmethod
-    def prop_stype(rf):
+    #}}}
+
+    @staticmethod
+    def prop_stype(rf): #{{{
         stype = []
         return stype
-
-    @staticmethod
-    def prop_scale(rf):
+    #}}}
+
+    @staticmethod
+    def prop_scale(rf): #{{{
         scale = []
         return scale
-
-    @staticmethod
-    def prop_weight(rf):
+    #}}}
+
+    @staticmethod
+    def prop_weight(rf): #{{{
         weight = []
         return weight
-
-    @staticmethod
-    def prop_lower(rf):
+    #}}}
+
+    @staticmethod
+    def prop_lower(rf): #{{{
         lower = []
         return lower
-
-    @staticmethod
-    def prop_upper(rf):
+    #}}}
+
+    @staticmethod
+    def prop_upper(rf): #{{{
         upper = []
         return upper
-
-    @staticmethod
-    def prop_target(rf):
+    #}}}
+
+    @staticmethod
+    def prop_target(rf): #{{{
         target = []
         return target
+    #}}}
 
     @staticmethod
     def prop_levels(rf):
-        # response_function is always a vector, or should be, even with just 1
-        if type(rf) not in [list, np.ndarray]:
-            rf = [rf]
-
         respl = empty_nd_list(np.size(rf))
         probl = empty_nd_list(np.size(rf))
         rell = empty_nd_list(np.size(rf))
         grell = empty_nd_list(np.size(rf))
-
         for i in range(np.size(rf)):
             respl[i] = rf[i].respl
@@ -158,5 +184,4 @@
             rell[i] = rf[i].rell
             grell[i] = rf[i].grell
-
         respl = allempty(respl)
         probl = allempty(probl)
@@ -165,14 +190,25 @@
         return [respl, probl, rell, grell]
 
+    #new methods:
+    def isscaled(self): #{{{
+        if strncmpi(self.descriptor, 'scaled_', 7):
+            return True
+        else:
+            return False
+    #}}}
+
     @staticmethod
     def dakota_write(fidi, dresp, rdesc):
-        # collect only the responses of the appropriate class
-        rf = [struc_class(vars(dresp)[i][j], 'response_function', 'rf') for i in fieldnames(dresp) for j in range(len(vars(dresp)[i]))]
-
         #possible namespace pollution here
         from rlist_write import rlist_write
-        # write responses
-        rdesc = rlist_write(fidi, 'response_function', 'rf', rf, rdesc)
-
+        # collect only the responses of the appropriate class
+        #rf = [struc_class(vars(dresp)[i][j], 'response_function', 'rf') for i in fieldnames(dresp) for j in range(len(vars(dresp)[i]))]
+        resp = deepcopy(dresp)
+        fields = fieldnames(resp)
+        for field in fields:
+            if getattr(resp, field)[0].__class__.__name__ != 'response_function':
+                delattr(resp, field)
+        if len(resp) > 0:
+            rdesc = rlist_write(fidi, 'response_function', 'rf', resp, rdesc)
         return rdesc
 
Index: issm/trunk/src/m/classes/qmu/uniform_uncertain.m
===================================================================
--- issm/trunk/src/m/classes/qmu/uniform_uncertain.m	(revision 24686)
+++ issm/trunk/src/m/classes/qmu/uniform_uncertain.m	(revision 25836)
@@ -1,177 +1,189 @@
+%UNIFORM_UNCERTAIN Class definition
 %
-%  definition for the uniform_uncertain class.
-%
-%  [uuv]=uniform_uncertain(varargin)
-%
-%  where the required varargin are:
-%    descriptor    (char, description, '')
-%    lower         (double, lower bound, -Inf)
-%    upper         (double, upper bound,  Inf)
-%
-%  note that zero arguments constructs a default instance; one
-%  argument of the class copies the instance; and three or more
-%  arguments constructs a new instance from the arguments.
-%
-%  "Copyright 2009, by the California Institute of Technology.
-%  ALL RIGHTS RESERVED. United States Government Sponsorship
-%  acknowledged. Any commercial use must be negotiated with
-%  the Office of Technology Transfer at the California Institute
-%  of Technology.  (J. Schiermeier, NTR 47078)
-%
-%  This software may be subject to U.S. export control laws.
-%  By accepting this  software, the user agrees to comply with
-%  all applicable U.S. export laws and regulations. User has the
-%  responsibility to obtain export licenses, or other export
-%  authority as may be required before exporting such information
-%  to foreign countries or providing access to foreign persons."
-%
+%%   Usage:
+%      nuv=uniform_uncertain('descriptor',descriptor,'lower',lower,'upper',upper,'partition',partition);
+%      where nuv is the uniform_uncertain object returned by the constructor, lower and upper are the 
+%      pdf distribution bounds, and partition is the partition vector for distributed variables. 
+%      Can be a partition %      vector over elements or vertices.
+% 
+%   Example:
+%      md.qmu.variables.rheology=uniform_uncertain('descriptor','RheologyBBar','lower',1e8,'upper',1e9);
+%      md.qmu.variables.rheology=uniform_uncertain('descriptor','RheologyBBar','lower',1e8,'upper',1e9,'partition',vpartition);
+% 
+
 classdef uniform_uncertain
-    properties
-        descriptor='';
-        lower     =-Inf;
-        upper     = Inf;
-    end
+	properties
+		descriptor	= '';
+		lower		= -Inf;
+		upper		= Inf;
+		partition	= [];
+		nsteps		= 0;
+	end
+	methods
+		function self=uniform_uncertain(varargin) %constructor {{{
 
-    methods
-        function [uuv]=uniform_uncertain(varargin)
+			%recover options: 
+			options=pairoptions(varargin{:});
 
-            switch nargin
+			%initialize fields: 
+			self.descriptor=getfieldvalue(options,'descriptor');
+			self.upper=getfieldvalue(options,'upper');
+			self.lower=getfieldvalue(options,'lower');
 
-%  create a default object
+			%if the variable is scaled, a partition vector should have been 
+			%supplied, and that partition vector should have as many partitions 
+			%as the lower and upper vectors:
+			if self.isscaled(),
+				self.partition=getfieldvalue(options,'partition');
+				self.nsteps=getfieldvalue(options,'nsteps',1);
+				npart=qmupart2npart(self.partition);
+				if npart~=size(self.upper,1),
+					error(['uniform_uncertain constructor: for the scaled variable' self.descriptor ' the row size of the upper field should be identical to the number of partitions']);
+				end
+				if npart~=size(self.lower,1),
+					error(['uniform_uncertain constructor: for the scaled variable' self.descriptor ' the row size of the lower field should be identical to the number of partitions']);
+				end
+				if self.nsteps~=size(self.upper,2),
+					error(['uniform_uncertain constructor: for the scaled variable ' self.descriptor ' the col size of the upper field should be identical to the number of time steps']);
+				end
+				if self.nsteps~=size(self.lower,2),
+					error(['uniform_uncertain constructor: for the scaled variable ' self.descriptor ' the col size of the lower field should be identical to the number of time steps']);
+				end
+			end
 
-                case 0
+		end %}}}
+		function disp(self) % {{{
 
-%  copy the object
+			disp(sprintf('   uniform uncertain variable: '));
+			fielddisplay(self,'descriptor','name tag');
+			fielddisplay(self,'lower','pdf lower bound');
+			fielddisplay(self,'upper','pdf upper bound');
+			if ~isempty(self.partition),
+				fielddisplay(self,'partition','partition vector defining where sampling will occur');
+			end
+			fielddisplay(self,'nsteps','number of time steps');
+		end 
+		%}}}
+		function md=checkconsistency(self,md,solution,analyses) % {{{
 
-                case 1
-                    if isa(varargin{1},'uniform_uncertain')
-                        uuv=varargin{1};
-                    else
-                        error('Object ''%s'' is a ''%s'' class object, not ''%s''.',...
-                            inputname(1),class(varargin{1}),'uniform_uncertain');
-                    end
+			md = checkfield(md,'field',self.upper,'fieldname','uniform_uncertain.upper','NaN',1,'Inf',1,'>',self.lower,'numel',length(self.lower));
+			md = checkfield(md,'field',self.lower,'fieldname','uniform_uncertain.lower','NaN',1,'Inf',1,'<',self.upper,'numel',length(self.upper));
+			if self.isscaled(),
+				if isempty(self.partition),
+					error('uniform_uncertain is a scaled variable, but it''s missing a partition vector');
+				end
+				%better have a partition vector that has as many partitions as upper and lower's size: 
+				if size(self.upper,1)~=partition_npart(self.partition),
+					error('uniform_uncertain error message: row size of upper and partition size should be identical');
+				end
+				if size(self.lower,1)~=partition_npart(self.partition),
+					error('uniform_uncertain error message: row size of lower and partition size should be identical');
+				end
+				%we need as steps in upper and lower as there are time steps: 
+				if size(self.upper,2)~=self.nsteps,
+					error('uniform_uncertain error message: col size of upper and number of time steps should be identical');
+				end
+				if size(self.lower,2)~=self.nsteps,
+					error('uniform_uncertain error message: col size of lower and number of time steps should be identical');
+				end
 
-%  not enough arguments
-
-                case 2
-                    error('Construction of ''%s'' class object requires at least %d inputs.',...
-                        'uniform_uncertain',3)
-
-%  create the object from the input
-
-                otherwise
-                    asizec=num2cell(array_size(varargin{1:min(nargin,3)}));
-                    uuv(asizec{:})=uniform_uncertain;
-                    clear asizec
-
-                    if ischar(varargin{1})
-                        varargin{1}=cellstr(varargin{1});
-                    end
-                    for i=1:numel(uuv)
-                        if (numel(varargin{1}) > 1)
-                            uuv(i).descriptor=varargin{1}{i};
-                        else
-                            uuv(i).descriptor=[char(varargin{1}) string_dim(uuv,i,'vector')];
-                        end
-                        if (numel(varargin{2}) > 1)
-                            uuv(i).lower     =varargin{2}(i);
-                        else
-                            uuv(i).lower     =varargin{2};
-                        end
-                        if (numel(varargin{3}) > 1)
-                            uuv(i).upper     =varargin{3}(i);
-                        else
-                            uuv(i).upper     =varargin{3};
-                        end
-                    end
-            end
-
-        end
-
-        function []=disp(uuv)
-
-%  display the object
-
-            disp(sprintf('\n'));
-            for i=1:numel(uuv)
-                disp(sprintf('class ''%s'' object ''%s%s'' = \n',...
-                    class(uuv),inputname(1),string_dim(uuv,i)));
-                disp(sprintf('    descriptor: ''%s'''  ,uuv(i).descriptor));
-                disp(sprintf('         lower: %g'      ,uuv(i).lower));
-                disp(sprintf('         upper: %g\n'    ,uuv(i).upper));
-            end
-
-        end
-
-        function [desc]  =prop_desc(uuv,dstr)
-            desc=cell(1,numel(uuv));
-            for i=1:numel(uuv)
-                if ~isempty(uuv(i).descriptor)
-                    desc(i)=cellstr(uuv(i).descriptor);
-                elseif ~isempty(inputname(1))
-                    desc(i)=cellstr([inputname(1) string_dim(uuv,i,'vector')]);
-                elseif exist('dstr','var')
-                    desc(i)=cellstr([dstr         string_dim(uuv,i,'vector')]);
-                else
-                    desc(i)=cellstr(['uuv'        string_dim(uuv,i,'vector')]);
-                end
-            end
-            desc=allempty(desc);
-        end
-        function [initpt]=prop_initpt(uuv)
-            initpt=[];
-        end
-        function [lower] =prop_lower(uuv)
-            lower=zeros(1,numel(uuv));
-            for i=1:numel(uuv)
-                lower(i)=uuv(i).lower;
-            end
-            lower=allequal(lower,-Inf);
-        end
-        function [upper] =prop_upper(uuv)
-            upper=zeros(1,numel(uuv));
-            for i=1:numel(uuv)
-                upper(i)=uuv(i).upper;
-            end
-            upper=allequal(upper, Inf);
-        end
-        function [mean]  =prop_mean(uuv)
-            mean=[];
-        end
-        function [stddev]=prop_stddev(uuv)
-            stddev=[];
-        end
-        function [initst]=prop_initst(uuv)
-            initst=[];
-        end
-        function [stype] =prop_stype(uuv)
-            stype={};
-        end
-        function [scale] =prop_scale(uuv)
-            scale=[];
-        end
-		function [abscissas] =prop_abscissas(hbu) % {{{
-            abscissas=[]; 
-        end % }}}
-        function [counts] =prop_counts(hbu) % {{{
-            counts=[]; 
-        end % }}}
-        function [pairs_per_variable] =prop_pairs_per_variable(hbu) % {{{
+				md = checkfield(md,'field',self.partition,'fieldname','uniform_uncertain.partition','NaN',1,'Inf',1,'>=',-1,'numel',[md.mesh.numberofvertices,md.mesh.numberofelements]);
+				if size(self.partition,2)>1,
+					error('uniform_uncertain error message: partition should be a column vector');
+				end
+				partcheck=unique(self.partition); 
+				partmin=min(partcheck); 
+				partmax=max(partcheck);
+				if partmax<-1,
+					error('uniform_uncertain error message: partition vector''s min value should be -1 (for no partition), or start at 0');
+				end
+				nmax=max(md.mesh.numberofelements,md.mesh.numberofvertices);
+				if partmax>nmax,
+					error('uniform_uncertain error message: partition vector''s values cannot go over the number of vertices or elements');
+				end
+			end
+		end % }}}
+		%virtual functions needed by qmu processing algorithms:
+		%implemented:
+		function [desc]=prop_desc(uuv,dstr) % {{{
+			desc=cell(1,numel(uuv));
+			for i=1:numel(uuv)
+				if ~isempty(uuv(i).descriptor)
+					desc(i)=cellstr(uuv(i).descriptor);
+				elseif ~isempty(inputname(1))
+					desc(i)=cellstr([inputname(1) string_dim(uuv,i,'vector')]);
+				elseif exist('dstr','var')
+					desc(i)=cellstr([dstr         string_dim(uuv,i,'vector')]);
+				else
+					desc(i)=cellstr(['uuv'        string_dim(uuv,i,'vector')]);
+				end
+			end
+			desc=allempty(desc);
+		end %}}}
+		function [lower]=prop_lower(uuv) % {{{
+			lower=zeros(1,numel(uuv));
+			for i=1:numel(uuv)
+				lower(i)=uuv(i).lower;
+			end
+			lower=allequal(lower,-Inf);
+		end %}}}
+		function [upper]=prop_upper(uuv) % {{{
+			upper=zeros(1,numel(uuv));
+			for i=1:numel(uuv)
+				upper(i)=uuv(i).upper;
+			end
+			%upper=allequal(upper, Inf);
+		end % }}}
+		%default
+		function [stddev]=prop_stddev(uuv)  %{{{
+			stddev=[];
+		end % }}}
+		function [mean]=prop_mean(nuv) % {{{
+			mean=[];
+		end % }}}
+		function [initpt]=prop_initpt(uuv) %{{{
+			initpt=[];
+		end %}}}
+		function [initst]=prop_initst(uuv) %{{{
+			initst=[];
+		end %}}}
+		function [stype]=prop_stype(uuv) %{{{
+			stype={};
+		end %}}}
+		function [scale]=prop_scale(uuv) %{{{
+			scale=[];
+		end %}}}
+		function [abscissas]=prop_abscissas(hbu) % {{{
+			abscissas=[]; 
+		end % }}}
+		function [counts]=prop_counts(hbu) % {{{
+			counts=[]; 
+		end % }}}
+		function [pairs_per_variable]=prop_pairs_per_variable(hbu) % {{{
 			pairs_per_variable=[];
-        end % }}}
-
-    end
-
-    methods (Static)
-        function []=dakota_write(fidi,dvar)
-
-%  collect only the variables of the appropriate class
-
-            uuv=struc_class(dvar,'uniform_uncertain');
-
-%  write variables
-
-            vlist_write(fidi,'uniform_uncertain','uuv',uuv);
-        end
-    end
+		end % }}}
+		%new methods: 
+			function distributed=isdistributed(self) % {{{
+			if strncmp(self.descriptor,'distributed_',12),
+				distributed=1;
+			else
+				distributed=0;
+			end
+		end % }}}
+	function scaled=isscaled(self) % {{{
+			if strncmp(self.descriptor,'scaled_',7),
+				scaled=1;
+			else
+				scaled=0;
+			end
+		end % }}}
+	end
+	methods (Static)
+		function []=dakota_write(fidi,dvar) % {{{
+			%  collect only the variables of the appropriate class
+			uuv=struc_class(dvar,'uniform_uncertain');
+			%  write variables
+			vlist_write(fidi,'uniform_uncertain','uuv',uuv);
+		end %}}}
+	end
 end
Index: issm/trunk/src/m/classes/qmu/uniform_uncertain.py
===================================================================
--- issm/trunk/src/m/classes/qmu/uniform_uncertain.py	(revision 24686)
+++ issm/trunk/src/m/classes/qmu/uniform_uncertain.py	(revision 25836)
@@ -1,31 +1,52 @@
 import numpy as np
-#from vlist_write import *
+
 from MatlabArray import *
+from MatlabFuncs import *
+from fielddisplay import fielddisplay
+from pairoptions import pairoptions
+from partition_npart import *
+from qmupart2npart import qmupart2npart
 
 
 class uniform_uncertain(object):
     '''
-  definition for the uniform_uncertain class.
-
-  [uuv] = uniform_uncertain.uniform_uncertain(args)
-   uuv = uniform_uncertain()
-
-  where the required args are:
-    descriptor    (str, description, '')
-    lower         (float, lower bound, -np.Inf)
-    upper         (float, upper bound, np.Inf)
-
-  note that zero arguments constructs a default instance, one
-  argument of the class copies the instance, and three or more
-  arguments constructs a new instance from the arguments.
-'''
-
-    def __init__(self):
+    UNIFORM_UNCERTAIN class definition
+
+    Usage:
+        [uuv] = uniform_uncertain(
+            'descriptor', descriptor,
+            'lower', lower,
+            'upper', upper,
+            'partition', partition
+            )
+
+        where uuv is the uniform_uncertain object returned by the constructor, 
+        lower and upper are the pdf distribution bounds, and partition is the 
+        partition vector for distributed variables. Can be a partition vector 
+        over elements or vertices.
+
+    Example:
+        md.qmu.variables.rheology = uniform_uncertain(
+            'descriptor', 'RheologyBBar',
+            'lower', 1e8,
+            'upper', 1e9
+            )
+        md.qmu.variables.rheology = uniform_uncertain(
+            'descriptor', 'RheologyBBar',
+            'lower', 1e8,
+            'upper', 1e9,
+            'partition', vpartition
+            )
+    '''
+    def __init__(self): #{{{
         self.descriptor = ''
-        self.lower = -np.Inf
-        self.upper = np.Inf
-
-    @staticmethod
-    def uniform_uncertain(*args):
+        self.lower      = -np.inf
+        self.upper      = np.inf
+        self.partition  = []
+        self.nsteps     = 0
+    #}}}
+
+    @staticmethod
+    def uniform_uncertain(*args): #{{{
         nargin = len(args)
 
@@ -39,47 +60,91 @@
                 uuv = args[0]
             else:
-                raise RuntimeError('Object ' + str(args[0]) + ' is a ' + str(type(args[0])) + ' class object, not "uniform_uncertain".')
-
-        # not enough arguments
-        elif nargin == 2:
-            raise RuntimeError('Construction of "uniform_uncertain" class object requires at least 3 inputs.')
+                raise Exception('Object ' + str(args[0]) + ' is a ' + str(type(args[0])) + ' class object, not "uniform_uncertain".')
 
         # create the object from the input
         else:
-            # leaving this here in case it becomes important in the future
-            #asizec = array_size(*args[0:min(nargin, 3)])
-            #uuv = [uniform_uncertain() for i in range(asizec[0]) for j in range(asizec[1])]
             uuv = uniform_uncertain()
-            uuv.descriptor = str(args[0])
-            uuv.lower = args[1]
-            uuv.upper = args[2]
-        if (nargin > 3):
-            print('WARNING: uniform_uncertain:extra_arg: Extra arguments for object of class ' + type(uuv) + '.')
-
-        return [uuv]
-
-    def __repr__(self):
-        # display an individual object
-        string = '\n'
-        string += 'class "uniform_uncertain" object = \n'
-        string += '    descriptor: ' + str(self.descriptor) + '\n'
-        string += '         lower: ' + str(self.lower) + '\n'
-        string += '         upper: ' + str(self.upper) + '\n'
+
+            #recover options:
+            options = pairoptions(*args)
+
+            #initialize fields:
+            uuv.descriptor = options.getfieldvalue('descriptor')
+            uuv.lower      = options.getfieldvalue('lower')
+            uuv.upper      = options.getfieldvalue('upper')
+
+            #if the variable is scaled, a partition vector should have been 
+            #supplied, and  that partition vector should have as many 
+            #partitions as the lower and upper vectors:
+            if uuv.isscaled():
+                uuv.partition = options.getfieldvalue('partition')
+                uuv.nsteps = options.getfieldvalue('nsteps', 1)
+                npart = qmupart2npart(uuv.partition)
+                if npart != uuv.upper.shape[0]:
+                    raise Exception("uniform_uncertain constructor: for the scaled variable %s the upper field is not currently a vector of values for all the partitions described in the partition vector" % uuv.descriptor)
+                if npart != uuv.lower.shape[0]:
+                    raise Exception("uniform_uncertain constructor: for the scaled variable %s the lower field is not currently a vector of values for all the partitions described in the partition vector" % uuv.descriptor)
+                if uuv.nsteps != uuv.upper.shape[1]:
+                    raise Exception("uniform_uncertain constructor: for the scaled variable %s the col size of the upper field should be identical to the number of time steps" % uuv.descriptor)
+                if uuv.nsteps != uuv.lower.shape[1]:
+                    raise Exception("uniform_uncertain constructor: for the scaled variable %s the col size of the lower field should be identical to the number of time steps" % uuv.descriptor)
+
+        return [uuv] # Always return a list, so we have something akin to a MATLAB single row matrix
+    #}}}
+
+    def __repr__(self): #{{{
+        string = '   uniform uncertain variable: '
+        string = "%s\n%s" % (string, fielddisplay(self, 'descriptor', 'name tag'))
+        string = "%s\n%s" % (string, fielddisplay(self, 'lower', 'pdf lower bound'))
+        string = "%s\n%s" % (string, fielddisplay(self, 'upper', 'pdf upper bound'))
+        if self.partition != []:
+            string = "%s\n%s" % (string, fielddisplay(self, 'partition', 'partition vector defining where sampling will occur'))
+        string = "%s\n%s" % (string, fielddisplay(self, 'nsteps', 'number of time steps'))
 
         return string
-
-    # from here on, uuv is either a single, or a 1d vector of, uniform_uncertain
-
-    @staticmethod
-    def prop_desc(uuv, dstr):
-        if type(uuv) not in [list, np.ndarray]:
-            if uuv.descriptor != '' or type(uuv.descriptor) != str:
-                desc = str(uuv.descriptor)
-            elif dstr != '':
-                desc = str(dstr)
-            else:
-                desc = 'uuv'
-            return desc
-
+    #}}}
+
+    def __len__(self): #{{{
+        if type(self.lower) in [list, np.ndarray]:
+            return len(self.lower)
+        else:
+            return 1
+    #}}}
+    
+    def checkconsistency(self, md, solution, analyses): #{{{
+        md = checkfield(md, 'field', self.upper, 'fieldname', 'uniform_uncertain.upper', 'NaN', 1, 'Inf', 1, '>', self.lower, 'numel', len(self.lower))
+        md = checkfield(md, 'field', self.lower, 'fieldname', 'uniform_uncertain.upper', 'NaN', 1, 'Inf', 1, '<', self.upper, 'numel', len(self.upper))
+        if self.isscaled():
+            if self.partition == []:
+                raise Exception("uniform_uncertain is a scaled variable, but it's missing a partition vector")
+            #better have a partition vector that has as many partitions as 
+            #upper and lower's size:
+            if self.upper.shape[0] != partition_npart(self.partititon):
+                raise Exception("uniform_uncertain error message: row size of upper and partition size should be identical")
+            if self.lower.shape[0] != partition_npart(self.partition):
+                raise Exception("uniform_uncertain error message: row size of lower and partition size should be identical")
+            #we need as steps in upper and lower as there are time steps
+            if self.stddev.shape[1] != self.nsteps:
+                raise Exception("uniform_uncertain error message: col size of upper and partition size should be identical")
+            if self.mean.shape[1] != self.nsteps:
+                raise Exception("uniform_uncertain error message: col size of lower and partition size should be identical")
+            md = checkfield(md, 'field', self.partition, 'fieldname', 'uniform_uncertain.partition', 'NaN', 1, 'Inf', 1, '>=', -1, 'numel', [md.mesh.numberofvertices, md.mesh.numberofvertices])
+            if self.partition.shape[1] > 1:
+                raise Exception("uniform_uncertain error message: partition should be a column vector")
+            partcheck = np.unique(self.partition)
+            partmin = min(partcheck)
+            partmax = max(partcheck)
+            if partmax < -1:
+                raise Exception("uniform_uncertain error message: partition vector's min value should be -1 (for no partition), or start at 0")
+            nmax = max(md.mesh.numberofelements, md.mesh.numberofvertices)
+            if partmax > nmax:
+                raise Exception("uniform_uncertain error message: partition vector's values cannot go over the number of vertices or elements")
+    #}}}
+
+    #virtual functions needed by qmu processing algorithms:
+    #implemented:
+
+    @staticmethod
+    def prop_desc(uuv, dstr): #{{{
         desc = ['' for i in range(np.size(uuv))]
         for i in range(np.size(uuv)):
@@ -94,67 +159,101 @@
 
         return desc
-
-    @staticmethod
-    def prop_initpt(uuv):
-        initpt = []
-        return initpt
-
-    @staticmethod
-    def prop_lower(uuv):
-        if type(uuv) not in [list, np.ndarray]:
-            return uuv.lower
-
+    #}}}
+
+    @staticmethod
+    def prop_stddev(uuv): #{{{
+        stddev = []
+        return stddev
+    #}}}
+
+    @staticmethod
+    def prop_mean(uuv): #{{{
+        mean = []
+        return mean
+    #}}}
+
+    @staticmethod
+    def prop_lower(uuv): #{{{
         lower = np.zeros(np.size(uuv))
         for i in range(np.size(uuv)):
             lower[i] = uuv[i].lower
 
-        lower = allequal(lower, -np.Inf)
+        lower = allequal(lower, -np.inf)
 
         return lower
-
-    @staticmethod
-    def prop_upper(uuv):
-        if type(uuv) not in [list, np.ndarray]:
-            return uuv.upper
-
+    #}}}
+
+    @staticmethod
+    def prop_upper(uuv): #{{{
         upper = np.zeros(np.size(uuv))
         for i in range(np.size(uuv)):
             upper[i] = uuv[i].upper
 
-        upper = allequal(upper, np.Inf)
+        #upper = allequal(upper, np.inf)
 
         return upper
-
-    @staticmethod
-    def prop_mean(uuv):
-        mean = []
-        return mean
-
-    @staticmethod
-    def prop_stddev(uuv):
-        stddev = []
-        return stddev
-
-    @staticmethod
-    def prop_initst(uuv):
+    #}}}
+
+    @staticmethod
+    def prop_abscissas(hbu): #{{{
+        abscissas = []
+        return abscissas
+    #}}}
+
+    @staticmethod
+    def prop_pairs_per_variable(hbu): #{{{
+        pairs_per_variable = []
+        return pairs_per_variable
+    #}}}
+
+    @staticmethod
+    def prop_counts(hbu): #{{{
+        counts = []
+        return counts
+    #}}}
+
+    @staticmethod
+    def prop_initpt(uuv): #{{{
+        initpt = []
+        return initpt
+    #}}}
+
+    @staticmethod
+    def prop_initst(uuv): #{{{
         initst = []
         return initst
-
-    @staticmethod
-    def prop_stype(uuv):
+    #}}}
+
+    @staticmethod
+    def prop_stype(uuv): #{{{
         stype = []
         return stype
-
-    @staticmethod
-    def prop_scale(uuv):
+    #}}}
+
+    @staticmethod
+    def prop_scale(uuv): #{{{
         scale = []
         return scale
-
-    @staticmethod
-    def dakota_write(fidi, dvar):
-        # collect only the variables of the appropriate class
-        uuv = [struc_class(i, 'uniform_uncertain', 'uuv') for i in dvar]
+    #}}}
+
+    #new methods:
+    def isscaled(self): #{{{
+        if strncmp(self.descriptor, 'scaled_', 7):
+            return True
+        else:
+            return False
+    #}}}
+
+    @staticmethod
+    def dakota_write(fidi, dvar): #{{{
         # possible namespace pollution, the above import seems not to work
         from vlist_write import vlist_write
-        # write variables
-        vlist_write(fidi, 'uniform_uncertain', 'uuv', uuv)
+        # collect only the variables of the appropriate class
+        uuv = deepcopy(dvar)
+        fields = fieldnames(uuv)
+        for field in fields:
+            if getattr(uuv, field)[0].__class__.__name__ != 'uniform_uncertain':
+                delattr(uuv, field)
+        if len(uuv) > 0:
+            vlist_write(fidi, 'uniform_uncertain', 'uuv', uuv)
+    #}}}
