Index: /issm/trunk-jpl/src/m/classes/autodiff.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/autodiff.py	(revision 27743)
+++ /issm/trunk-jpl/src/m/classes/autodiff.py	(revision 27744)
@@ -9,9 +9,8 @@
 
 class autodiff(object):
-    """
-    AUTODIFF class definition
-
-       Usage:
-          autodiff = autodiff()
+    """autodiff class definition
+
+    Usage:
+        autodiff = autodiff()
     """
     def __init__(self, *args):  # {{{
@@ -20,11 +19,11 @@
         self.independents = []
         self.driver = 'fos_forward'
-        self.obufsize = float('NaN')
-        self.lbufsize = float('NaN')
-        self.cbufsize = float('NaN')
-        self.tbufsize = float('NaN')
-        self.gcTriggerMaxSize = float('NaN')
-        self.gcTriggerRatio = float('NaN')
-        self.tapeAlloc = float('NaN')
+        self.obufsize = np.nan
+        self.lbufsize = np.nan
+        self.cbufsize = np.nan
+        self.tbufsize = np.nan
+        self.gcTriggerMaxSize = np.nan
+        self.gcTriggerRatio = np.nan
+        self.tapeAlloc = np.nan
         if not len(args):
             self.setdefaultparameters()
@@ -34,16 +33,16 @@
 
     def __repr__(self):  # {{{
-        s = "      automatic differentiation parameters:\n"
-        s += "%s\n" % fielddisplay(self, 'isautodiff', "indicates if the automatic differentiation is activated")
-        s += "%s\n" % fielddisplay(self, 'dependents', "list of dependent variables")
-        s += "%s\n" % fielddisplay(self, 'independents', "list of independent variables")
-        s += "%s\n" % fielddisplay(self, 'driver', "ADOLC driver ('fos_forward' or 'fov_forward')")
-        s += "%s\n" % fielddisplay(self, 'obufsize', "Number of operations per buffer (== OBUFSIZE in usrparms.h)")
-        s += "%s\n" % fielddisplay(self, 'lbufsize', "Number of locations per buffer (== LBUFSIZE in usrparms.h)")
-        s += "%s\n" % fielddisplay(self, 'cbufsize', "Number of values per buffer (== CBUFSIZE in usrparms.h)")
-        s += "%s\n" % fielddisplay(self, 'tbufsize', "Number of taylors per buffer (<=TBUFSIZE in usrparms.h)")
-        s += "%s\n" % fielddisplay(self, 'gcTriggerRatio', "free location block sorting / consolidation triggered if the ratio between allocated and used locations exceeds gcTriggerRatio")
-        s += "%s\n" % fielddisplay(self, 'gcTriggerMaxSize', "free location block sorting / consolidation triggered if the allocated locations exceed gcTriggerMaxSize)")
-        s += "%s\n" % fielddisplay(self, 'tapeAlloc', 'Iteration count of a priori memory allocation of the AD tape')
+        s = '      automatic differentiation parameters:\n'
+        s += '{}\n'.format(fielddisplay(self, 'isautodiff', "indicates if the automatic differentiation is activated"))
+        s += '{}\n'.format(fielddisplay(self, 'dependents', "list of dependent variables"))
+        s += '{}\n'.format(fielddisplay(self, 'independents', "list of independent variables"))
+        s += '{}\n'.format(fielddisplay(self, 'driver', "ADOLC driver ('fos_forward' or 'fov_forward')"))
+        s += '{}\n'.format(fielddisplay(self, 'obufsize', "Number of operations per buffer (== OBUFSIZE in usrparms.h)"))
+        s += '{}\n'.format(fielddisplay(self, 'lbufsize', "Number of locations per buffer (== LBUFSIZE in usrparms.h)"))
+        s += '{}\n'.format(fielddisplay(self, 'cbufsize', "Number of values per buffer (== CBUFSIZE in usrparms.h)"))
+        s += '{}\n'.format(fielddisplay(self, 'tbufsize', "Number of taylors per buffer (<=TBUFSIZE in usrparms.h)"))
+        s += '{}\n'.format(fielddisplay(self, 'gcTriggerRatio', "free location block sorting / consolidation triggered if the ratio between allocated and used locations exceeds gcTriggerRatio"))
+        s += '{}\n'.format(fielddisplay(self, 'gcTriggerMaxSize', "free location block sorting / consolidation triggered if the allocated locations exceed gcTriggerMaxSize)"))
+        s += '{}\n'.format(fielddisplay(self, 'tapeAlloc', 'Iteration count of a priori memory allocation of the AD tape'))
 
         return s
@@ -62,5 +61,5 @@
 
     def checkconsistency(self, md, solution, analyses):  # {{{
-        #Early return
+        # Early return
         if not self.isautodiff:
             return md
@@ -74,8 +73,8 @@
         md = checkfield(md, 'fieldname', 'autodiff.tapeAlloc', '>=', 0)
 
-    #Driver value:
+        # Driver value
         md = checkfield(md, 'fieldname', 'autodiff.driver', 'values', ['fos_forward', 'fov_forward', 'fov_forward_all', 'fos_reverse', 'fov_reverse', 'fov_reverse_all'])
 
-    #go through our dependents and independents and check consistency:
+        # Go through our dependents and independents and check consistency
         for dep in self.dependents:
             dep.checkconsistency(md, solution, analyses)
@@ -90,5 +89,5 @@
         WriteData(fid, prefix, 'object', self, 'fieldname', 'driver', 'format', 'String')
 
-        #early return
+        # Early return
         if not self.isautodiff:
             WriteData(fid, prefix, 'data', False, 'name', 'md.autodiff.mass_flux_segments_present', 'format', 'Boolean')
@@ -96,5 +95,5 @@
             return
 
-        #buffer sizes {{{
+        # Buffer sizes
         WriteData(fid, prefix, 'object', self, 'fieldname', 'obufsize', 'format', 'Double')
         WriteData(fid, prefix, 'object', self, 'fieldname', 'lbufsize', 'format', 'Double')
@@ -104,6 +103,6 @@
         WriteData(fid, prefix, 'object', self, 'fieldname', 'gcTriggerMaxSize', 'format', 'Double')
         WriteData(fid, prefix, 'object', self, 'fieldname', 'tapeAlloc', 'format', 'Integer')
-        # }}}
-        #process dependent variables {{{
+
+        # Process dependent variables
         num_dependent_objects = len(self.dependents)
         WriteData(fid, prefix, 'data', num_dependent_objects, 'name', 'md.autodiff.num_dependent_objects', 'format', 'Integer')
@@ -111,29 +110,22 @@
         if num_dependent_objects:
             names = []
-            indices = np.zeros(num_dependent_objects)
-
             for i, dep in enumerate(self.dependents):
                 names.append(dep.name)
-                indices[i] = dep.index
 
             WriteData(fid, prefix, 'data', names, 'name', 'md.autodiff.dependent_object_names', 'format', 'StringArray')
-            WriteData(fid, prefix, 'data', indices, 'name', 'md.autodiff.dependent_object_indices', 'format', 'IntMat', 'mattype', 3)
-            # }}}
-        #process independent variables {{{
+
+        # Process independent variables
         num_independent_objects = len(self.independents)
         WriteData(fid, prefix, 'data', num_independent_objects, 'name', 'md.autodiff.num_independent_objects', 'format', 'Integer')
 
-        if num_independent_objects:
-            names = [None] * num_independent_objects
-            types = np.zeros(num_independent_objects)
-
-            for i, indep in enumerate(self.independents):
-                names[i] = indep.name
-                types[i] = indep.typetoscalar()
-
-            WriteData(fid, prefix, 'data', names, 'name', 'md.autodiff.independent_object_names', 'format', 'StringArray')
-            WriteData(fid, prefix, 'data', types, 'name', 'md.autodiff.independent_object_types', 'format', 'IntMat', 'mattype', 3)
-            # }}}
-        #if driver is fos_forward, build index:  {{{
+        for indep in self.independents:
+            WriteData(fid, prefix, 'data', indep.name, 'name', 'md.autodiff.independent_name', 'format', 'String')
+            WriteData(fid, prefix, 'data', indep.typetoscalar(), 'name', 'md.autodiff.independent_type', 'format', 'Integer')
+            WriteData(fid, prefix, 'data', indep.min_parameters, 'name','md.autodiff.independent_min_parameters','format', 'DoubleMat', 'mattype', 3)
+            WriteData(fid, prefix, 'data', indep.max_parameters, 'name', 'md.autodiff.independent_max_parameters', 'format', 'DoubleMat', 'mattype', 3)
+            WriteData(fid, prefix, 'data', indep.control_scaling_factor, 'name', 'md.autodiff.independent_scaling_factor', 'format', 'Double')
+            WriteData(fid, prefix, 'data', indep.control_size, 'name', 'md.autodiff.independent_control_size', 'format', 'Integer')
+
+        # If driver is fos_forward, build index
         if strcmpi(self.driver, 'fos_forward'):
             index = 0
@@ -149,8 +141,8 @@
                         index += indep.nods
 
-            index -= 1  #get c - index numbering going
+            index -= 1  # get c-index numbering going
             WriteData(fid, prefix, 'data', index, 'name', 'md.autodiff.fos_forward_index', 'format', 'Integer')
-            # }}}
-        #if driver is fos_reverse, build index:  {{{
+
+        # If driver is fos_reverse, build index
         if strcmpi(self.driver, 'fos_reverse'):
             index = 0
@@ -163,8 +155,8 @@
                     index += 1
 
-            index -= 1  #get c - index numbering going
+            index -= 1  # get c-index numbering going
             WriteData(fid, prefix, 'data', index, 'name', 'md.autodiff.fos_reverse_index', 'format', 'Integer')
-            # }}}
-        #if driver is fov_forward, build indices:  {{{
+
+        # If driver is fov_forward, build indices
         if strcmpi(self.driver, 'fov_forward'):
             indices = 0
@@ -180,8 +172,8 @@
                         indices += indep.nods
 
-            indices -= 1  #get c - indices numbering going
+            indices -= 1  # get c-indices numbering going
             WriteData(fid, prefix, 'data', indices, 'name', 'md.autodiff.fov_forward_indices', 'format', 'IntMat', 'mattype', 3)
-            # }}}
-        #deal with mass fluxes:  {{{
+
+        # Deal with mass fluxes
         mass_flux_segments = [dep.segments for dep in self.dependents if strcmpi(dep.name, 'MassFlux')]
 
@@ -192,16 +184,18 @@
             flag = False
         WriteData(fid, prefix, 'data', flag, 'name', 'md.autodiff.mass_flux_segments_present', 'format', 'Boolean')
-        # }}}
-        #deal with trace keep on: {{{
+
+        # Deal with trace keep on
         keep = False
 
-        #From ADOLC userdoc:
-        # The optional integer argument keep of trace on determines whether the numerical values of all active variables are
-        # recorded in a buffered temporary array or file called the taylor stack. This option takes effect if keep = 1 and
-        # prepares the scene for an immediately following gradient evaluation by a call to a routine implementing the reverse
-        # mode as described in the Section 4 and Section 5.
+        # From ADOLC userdoc:
+        # The optional integer argument keep of trace on determines whether the 
+        # numerical values of all active variables are recorded in a buffered 
+        # temporary array or file called the taylor stack. This option takes 
+        # effect if keep = 1 and prepares the scene for an immediately 
+        # following gradient evaluation by a call to a routine implementing the 
+        # reverse mode as described in the Section 4 and Section 5.
         #
         if len(self.driver) <= 3:
-            keep = False  #there is no "_reverse" string within the driver string:
+            keep = False  # there is no "_reverse" string within the driver string
         else:
             if strncmpi(self.driver[3:], '_reverse', 8):
Index: /issm/trunk-jpl/src/m/classes/independent.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/independent.m	(revision 27743)
+++ /issm/trunk-jpl/src/m/classes/independent.m	(revision 27744)
@@ -66,5 +66,5 @@
 			fielddisplay(self,'name','variable name (must match corresponding String)');
 			fielddisplay(self,'type','type of variable (''vertex'' or ''scalar'')');
-			fielddisplay(self,'nods','size of dependent variables');
+			fielddisplay(self,'nods','size of independent variables');
 			fielddisplay(self,'control_size','number of timesteps');
 			fielddisplay(self,'min_parameters','absolute minimum acceptable value of the inversed parameter on each vertex');
Index: /issm/trunk-jpl/src/m/classes/independent.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/independent.py	(revision 27743)
+++ /issm/trunk-jpl/src/m/classes/independent.py	(revision 27744)
@@ -7,9 +7,8 @@
 
 class independent(object):
-    """
-    INDEPENDENT class definition
+    """independent class definition
 
-       Usage:
-          independent = independent()
+    Usage:
+        independent = independent()
     """
 
@@ -17,27 +16,39 @@
         self.name = ''
         self.type = ''
-        self.fos_forward_index = float('NaN')
+        self.fos_forward_index = np.nan
         self.fov_forward_indices = np.array([])
         self.nods = 0
+        self.min_parameters = np.nan
+        self.max_parameters = np.nan
+        self.control_scaling_factor = np.nan
+        self.control_size = 0
 
-    #set defaults
+        # Set defaults
         self.setdefaultparameters()
 
-    #use provided options to change fields
+        # Use provided options to change fields
         options = pairoptions(*args)
 
-    #OK get other fields
+        # Get other fields
         self = options.AssignObjectFields(self)
+
+        if self.control_size == 0:
+            self.control_size = 1
     # }}}
 
     def __repr__(self):  # {{{
-        s = "   independent variable:\n"
+        s = '   independent variable:\n'
 
-        s += "%s\n" % fielddisplay(self, 'name', "variable name (must match corresponding String)")
-        s += "%s\n" % fielddisplay(self, 'type', "type of variable ('vertex' or 'scalar')")
+        s += '{}\n'.format(fielddisplay(self, 'name', 'variable name (must match corresponding String)'))
+        s += '{}\n'.format(fielddisplay(self, 'type', 'type of variable (\'vertex\' or \'scalar\')'))
+        s += '{}\n'.format(fielddisplay(self, 'nods', 'size of independent variables'))
+        s += '{}\n'.format(fielddisplay(self, 'control_size', 'number of timesteps'))
+        s += '{}\n'.format(fielddisplay(self, 'min_parameters', 'absolute minimum acceptable value of the inversed parameter on each vertex'))
+        s += '{}\n'.format(fielddisplay(self, 'max_parameters', 'absolute maximum acceptable value of the inversed parameter on each vertex'))
+        s += '{}\n'.format(fielddisplay(self, 'control_scaling_factor', 'order of magnitude of each control (useful for multi-parameter optimization)'))
         if not np.isnan(self.fos_forward_index):
-            s += "%s\n" % fielddisplay(self, 'fos_forward_index', "index for fos_foward driver of ADOLC")
+            s += '{}\n'.format(fielddisplay(self, 'fos_forward_index', 'index for fos_foward driver of ADOLC'))
         if np.any(np.logical_not(np.isnan(self.fov_forward_indices))):
-            s += "%s\n" % fielddisplay(self, 'fov_forward_indices', "indices for fov_foward driver of ADOLC")
+            s += '{}\n'.format(fielddisplay(self, 'fov_forward_indices', 'indices for fov_foward driver of ADOLC'))
 
         return s
@@ -45,5 +56,5 @@
 
     def setdefaultparameters(self):  # {{{
-        #do nothing
+        # Do nothing
         return self
     # }}}
@@ -52,14 +63,14 @@
         if not np.isnan(self.fos_forward_index):
             if not strcmpi(driver, 'fos_forward'):
-                raise TypeError("cannot declare an independent with a fos_forward_index when the driver is not fos_forward!")
+                raise TypeError('cannot declare an independent with a fos_forward_index when the driver is not fos_forward!')
             if self.nods == 0:
-                raise TypeError("independent checkconsistency error: nods should be set to the size of the independent variable")
+                raise TypeError('independent checkconsistency error: nods should be set to the size of the independent variable')
 
         if len(self.fov_forward_indices) > 0:
             if not strcmpi(driver, 'fov_forward'):
-                raise TypeError("cannot declare an independent with fov_forward_indices when the driver is not fov_forward!")
+                raise TypeError('cannot declare an independent with fov_forward_indices when the driver is not fov_forward!')
             if self.nods == 0:
-                raise TypeError("independent checkconsistency error: nods should be set to the size of the independent variable")
-            md = checkfield(md, 'fieldname', "autodiff.independents[%d].fov_forward_indices" % i, '>=', 1, '<=', self.nods)
+                raise TypeError('independent checkconsistency error: nods should be set to the size of the independent variable')
+            md = checkfield(md, 'fieldname', 'autodiff.independents[%d].fov_forward_indices' % i, '>=', 1, '<=', self.nods)
 
         return md
@@ -68,8 +79,12 @@
     def typetoscalar(self):  # {{{
         if strcmpi(self.type, 'scalar'):
-            scalar = 0
+            scalartype = 0
         elif strcmpi(self.type, 'vertex'):
-            scalar = 1
+            scalartype = 1
+        elif strcmpi(self.type, 'matrix'):
+            scalartype = 1
+        else:
+            raise TypeError('{} not supported yet!'.format(self.type))
 
-        return scalar
+        return scalartype
     # }}}
