Index: /issm/trunk-jpl/src/m/classes/autodiff.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/autodiff.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/autodiff.py	(revision 13023)
@@ -1,6 +1,16 @@
 #module imports
 from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import *
+from WriteData import *
 
 class autodiff(object):
+	"""
+	AUTODIFF class definition
+
+	   Usage:
+	      autodiff=autodiff();
+	"""
+
 	#properties
 	def __init__(self):
@@ -14,15 +24,25 @@
 
 		#}}}
-	def __repr__(obj):
+	def __repr__(self):
 		# {{{ Display
 		string='   automatic differentiation parameters:'
-		string="%s\n%s"%(string,fielddisplay(obj,'isautodiff','indicates if the automatic differentiation is activated'))
-		string="%s\n%s"%(string,fielddisplay(obj,'forward','forward differentiation'))
-		string="%s\n%s"%(string,fielddisplay(obj,'reverse','backward differentiation'))
+		string="%s\n%s"%(string,fielddisplay(self,'isautodiff','indicates if the automatic differentiation is activated'))
+		string="%s\n%s"%(string,fielddisplay(self,'forward','forward differentiation'))
+		string="%s\n%s"%(string,fielddisplay(self,'reverse','backward differentiation'))
 		return string
 		#}}}
-	def setdefaultparameters(obj):
+	def setdefaultparameters(self):
 		# {{{setdefaultparameters
-		return obj
+		return self
 	#}}}
 
+	def checkconsistency(self,md,solution,analyses):    # {{{
+		return md
+	# }}}
+
+	def marshall(self,fid):    # {{{
+		WriteData(fid,'object',self,'fieldname','isautodiff','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','forward','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','reverse','format','Boolean')
+	# }}}
+
Index: /issm/trunk-jpl/src/m/classes/clusters/generic.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/generic.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/clusters/generic.py	(revision 13023)
@@ -73,5 +73,5 @@
 
 		#write queuing script 
-		if not 'Windows' in platform.system():
+		if 'Windows' not in platform.system():
 
 			fid=open(modelname+'.queue','w')
@@ -115,5 +115,5 @@
 
 		#write queuing script 
-		if not 'Windows' in platform.system():
+		if 'Windows' not in platform.system():
 
 			fid=open(modelname+'.queue','w')
Index: /issm/trunk-jpl/src/m/classes/diagnostic.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/diagnostic.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/diagnostic.py	(revision 13023)
@@ -113,7 +113,7 @@
 
 		#Early return
-		if not DiagnosticHorizAnalysisEnum() in analyses:
+		if DiagnosticHorizAnalysisEnum() not in analyses:
 			return md
-		#if (not DiagnosticHorizAnalysisEnum() in analyses) | (solution==TransientSolutionEnum() and not md.transient.isdiagnostic):
+		#if (DiagnosticHorizAnalysisEnum() not in analyses) | (solution==TransientSolutionEnum() and not md.transient.isdiagnostic):
 		#	return md
 
Index: /issm/trunk-jpl/src/m/classes/flaim.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/flaim.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/flaim.py	(revision 13023)
@@ -1,6 +1,17 @@
 #module imports
+import numpy
 from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import *
+from WriteData import *
 
 class flaim(object):
+	"""
+	FLAIM class definition
+
+	   Usage:
+	      flaim=flaim();
+	"""
+
 	#properties
 	def __init__(self):
@@ -20,31 +31,47 @@
 		self.opt_niter          = 30000
 		#}}}
-	def __repr__(obj):
+	def __repr__(self):
 		# {{{ Displa
 		string='   FLAIM - Flight Line Adaptation using Ice sheet Modeling:'
 
 		string="%s\n\n%s"%(string,'      Input:')
-		string="%s\n%s"%(string,fielddisplay(obj,'targets'            ,'name of kml output targets file '))
-		string="%s\n%s"%(string,fielddisplay(obj,'tracks'             ,'name of kml input tracks file '))
-		string="%s\n%s"%(string,fielddisplay(obj,'flightreqs'         ,'structure of kml flight requirements (not used yet)'))
-		string="%s\n%s"%(string,fielddisplay(obj,'criterion'          ,'element or nodal criterion for flight path evaluation (metric)'))
+		string="%s\n%s"%(string,fielddisplay(self,'targets'            ,'name of kml output targets file '))
+		string="%s\n%s"%(string,fielddisplay(self,'tracks'             ,'name of kml input tracks file '))
+		string="%s\n%s"%(string,fielddisplay(self,'flightreqs'         ,'structure of kml flight requirements (not used yet)'))
+		string="%s\n%s"%(string,fielddisplay(self,'criterion'          ,'element or nodal criterion for flight path evaluation (metric)'))
 
 		string="%s\n\n%s"%(string,'      Arguments:')
-		string="%s\n%s"%(string,fielddisplay(obj,'gridsatequator'     ,'number of grids at equator (determines resolution)'))
-		string="%s\n%s"%(string,fielddisplay(obj,'usevalueordering'   ,'flag to consider target values for flight path evaluation'))
-		string="%s\n%s"%(string,fielddisplay(obj,'split_antimeridian' ,'flag to split polygons on the antimeridian'))
+		string="%s\n%s"%(string,fielddisplay(self,'gridsatequator'     ,'number of grids at equator (determines resolution)'))
+		string="%s\n%s"%(string,fielddisplay(self,'usevalueordering'   ,'flag to consider target values for flight path evaluation'))
+		string="%s\n%s"%(string,fielddisplay(self,'split_antimeridian' ,'flag to split polygons on the antimeridian'))
 		
 		string="%s\n\n%s"%(string,'      Optimization:')
-		string="%s\n%s"%(string,fielddisplay(obj,'path_optimize'     ,'optimize? (default false)'))
-		string="%s\n%s"%(string,fielddisplay(obj,'opt_ndir'     ,['number of directions to test when moving a point.  If this value = 1, a random direction is tested.',\
+		string="%s\n%s"%(string,fielddisplay(self,'path_optimize'     ,'optimize? (default false)'))
+		string="%s\n%s"%(string,fielddisplay(self,'opt_ndir'     ,['number of directions to test when moving a point.  If this value = 1, a random direction is tested.',\
 										  'A value > 1 results in directions equally spaced from [0, 2*PI] being tested.',\
 										  'For example, 4 would result in directions [0, PI/2, PI, 3PI/2].']))
-		string="%s\n%s"%(string,fielddisplay(obj,'opt_dist'     ,'specifies the distance in km (default 25) to move a randomly selected path point on each iteration'))
-		string="%s\n%s"%(string,fielddisplay(obj,'opt_niter'     ,['number of iterations (default 30,000) to run for flightplan optimization',\
+		string="%s\n%s"%(string,fielddisplay(self,'opt_dist'     ,'specifies the distance in km (default 25) to move a randomly selected path point on each iteration'))
+		string="%s\n%s"%(string,fielddisplay(self,'opt_niter'     ,['number of iterations (default 30,000) to run for flightplan optimization',\
 										   'i.e. the number of times to randomly select a point and move it.']))
 
 		string="%s\n\n%s"%(string,'      Output:')
-		string="%s\n%s"%(string,fielddisplay(obj,'solution'           ,'name of kml solution file'))
-		string="%s\n%s"%(string,fielddisplay(obj,'quality'            ,'quality of kml solution'))
+		string="%s\n%s"%(string,fielddisplay(self,'solution'           ,'name of kml solution file'))
+		string="%s\n%s"%(string,fielddisplay(self,'quality'            ,'quality of kml solution'))
 		return string
 		#}}}
+
+	def checkconsistency(self,md,solution,analyses):    # {{{
+
+		#Early return
+		if not solution==FlaimSolutionEnum():
+			return md
+
+		md = checkfield(md,'flaim.tracks','file',1)
+		if any(numpy.isnan(md.flaim.criterion)) or not md.flaim.criterion:
+			md = checkfield(md,'flaim.targets','file',1)
+		else:
+			md = checkfield(md,'flaim.criterion','numel',[md.mesh.numberofvertices,md.mesh.numberofelements])
+
+		return md
+	# }}}
+
Index: /issm/trunk-jpl/src/m/classes/friction.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/friction.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/friction.py	(revision 13023)
@@ -41,5 +41,5 @@
 
 		#Early return
-		if not DiagnosticHorizAnalysisEnum() in analyses and not ThermalAnalysisEnum() in analyses:
+		if DiagnosticHorizAnalysisEnum() not in analyses and ThermalAnalysisEnum() not in analyses:
 			return md
 
Index: /issm/trunk-jpl/src/m/classes/hydrology.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/hydrology.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/hydrology.py	(revision 13023)
@@ -61,5 +61,5 @@
 
 		#Early return
-		if not HydrologyAnalysisEnum() in analyses:
+		if HydrologyAnalysisEnum() not in analyses:
 			return md
 
Index: /issm/trunk-jpl/src/m/classes/inversion.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/inversion.m	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/inversion.m	(revision 13023)
@@ -1,3 +1,3 @@
-%CONSTANTS class definition
+%INVERSION class definition
 %
 %   Usage:
Index: /issm/trunk-jpl/src/m/classes/inversion.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/inversion.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/inversion.py	(revision 13023)
@@ -1,6 +1,17 @@
 #module imports
+import numpy
 from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import *
+from WriteData import *
 
 class inversion(object):
+	"""
+	INVERSION class definition
+
+	   Usage:
+	      inversion=inversion();
+	"""
+
 	#properties
 	def __init__(self):
@@ -26,24 +37,24 @@
 		self.thickness_obs               = float('NaN')
 		#}}}
-	def __repr__(obj):
+	def __repr__(self):
 		# {{{ Display
 		string='\n   Inversion parameters:'
-		string="%s\n%s"%(string,fielddisplay(obj,'iscontrol','is inversion activated?'))
-		string="%s\n%s"%(string,fielddisplay(obj,'incomplete_adjoint','do we assume linear viscosity?'))
-		string="%s\n%s"%(string,fielddisplay(obj,'control_parameters','parameter where inverse control is carried out; ex: {''FrictionCoefficient''}, or {''MaterialsRheologyBbar''}'))
-		string="%s\n%s"%(string,fielddisplay(obj,'nsteps','number of optimization searches'))
-		string="%s\n%s"%(string,fielddisplay(obj,'cost_functions','indicate the type of response for each optimization step'))
-		string="%s\n%s"%(string,fielddisplay(obj,'cost_functions_coefficients','cost_functions_coefficients applied to the misfit of each vertex and for each control_parameter'))
-		string="%s\n%s"%(string,fielddisplay(obj,'cost_function_threshold','misfit convergence criterion. Default is 1%, NaN if not applied'))
-		string="%s\n%s"%(string,fielddisplay(obj,'maxiter_per_step','maximum iterations during each optimization step'))
-		string="%s\n%s"%(string,fielddisplay(obj,'gradient_scaling','scaling factor on gradient direction during optimization, for each optimization step'))
-		string="%s\n%s"%(string,fielddisplay(obj,'step_threshold','decrease threshold for misfit, default is 30%'))
-		string="%s\n%s"%(string,fielddisplay(obj,'min_parameters','absolute minimum acceptable value of the inversed parameter on each vertex'))
-		string="%s\n%s"%(string,fielddisplay(obj,'max_parameters','absolute maximum acceptable value of the inversed parameter on each vertex'))
-		string="%s\n%s"%(string,fielddisplay(obj,'gradient_only','stop control method solution at gradient'))
-		string="%s\n%s"%(string,fielddisplay(obj,'vx_obs','observed velocity x component [m/a]'))
-		string="%s\n%s"%(string,fielddisplay(obj,'vy_obs','observed velocity y component [m/a]'))
-		string="%s\n%s"%(string,fielddisplay(obj,'vel_obs','observed velocity magnitude [m/a]'))
-		string="%s\n%s"%(string,fielddisplay(obj,'thickness_obs','observed thickness [m]'))
+		string="%s\n%s"%(string,fielddisplay(self,'iscontrol','is inversion activated?'))
+		string="%s\n%s"%(string,fielddisplay(self,'incomplete_adjoint','do we assume linear viscosity?'))
+		string="%s\n%s"%(string,fielddisplay(self,'control_parameters','parameter where inverse control is carried out; ex: {''FrictionCoefficient''}, or {''MaterialsRheologyBbar''}'))
+		string="%s\n%s"%(string,fielddisplay(self,'nsteps','number of optimization searches'))
+		string="%s\n%s"%(string,fielddisplay(self,'cost_functions','indicate the type of response for each optimization step'))
+		string="%s\n%s"%(string,fielddisplay(self,'cost_functions_coefficients','cost_functions_coefficients applied to the misfit of each vertex and for each control_parameter'))
+		string="%s\n%s"%(string,fielddisplay(self,'cost_function_threshold','misfit convergence criterion. Default is 1%, NaN if not applied'))
+		string="%s\n%s"%(string,fielddisplay(self,'maxiter_per_step','maximum iterations during each optimization step'))
+		string="%s\n%s"%(string,fielddisplay(self,'gradient_scaling','scaling factor on gradient direction during optimization, for each optimization step'))
+		string="%s\n%s"%(string,fielddisplay(self,'step_threshold','decrease threshold for misfit, default is 30%'))
+		string="%s\n%s"%(string,fielddisplay(self,'min_parameters','absolute minimum acceptable value of the inversed parameter on each vertex'))
+		string="%s\n%s"%(string,fielddisplay(self,'max_parameters','absolute maximum acceptable value of the inversed parameter on each vertex'))
+		string="%s\n%s"%(string,fielddisplay(self,'gradient_only','stop control method solution at gradient'))
+		string="%s\n%s"%(string,fielddisplay(self,'vx_obs','observed velocity x component [m/a]'))
+		string="%s\n%s"%(string,fielddisplay(self,'vy_obs','observed velocity y component [m/a]'))
+		string="%s\n%s"%(string,fielddisplay(self,'vel_obs','observed velocity magnitude [m/a]'))
+		string="%s\n%s"%(string,fielddisplay(self,'thickness_obs','observed thickness [m]'))
 		string="%s\n%s"%(string,'Available cost functions:')
 		string="%s\n%s"%(string,'   101: SurfaceAbsVelMisfit')
@@ -59,20 +70,20 @@
 		#}}}
 
-	def setdefaultparameters(obj):
+	def setdefaultparameters(self):
 		# {{{setdefaultparameters
 		
 		#default is incomplete adjoint for now
-		obj.incomplete_adjoint=1
+		self.incomplete_adjoint=1
 
 		#parameter to be inferred by control methods (only
 		#drag and B are supported yet)
-		obj.control_parameters=['FrictionCoefficient']
+		self.control_parameters=['FrictionCoefficient']
 
 		#number of steps in the control methods
-		obj.nsteps=20
+		self.nsteps=20
 
 		#maximum number of iteration in the optimization algorithm for
 		#each step
-		obj.maxiter_per_step=20*ones(obj.nsteps)
+		self.maxiter_per_step=20*ones(self.nsteps)
 
 		#the inversed parameter is updated as follows:
@@ -81,24 +92,98 @@
 		#inversed parameter (10^8 for B, 50 for drag) and can be decreased
 		#after the first iterations
-		obj.gradient_scaling=50*ones(obj.nsteps)
+		self.gradient_scaling=50*ones(self.nsteps)
 
 		#several responses can be used:
-		obj.cost_functions=101*ones(obj.nsteps)
+		self.cost_functions=101*ones(self.nsteps)
 
 		#step_threshold is used to speed up control method. When
-		#misfit(1)/misfit(0) < obj.step_threshold, we go directly to
+		#misfit(1)/misfit(0) < self.step_threshold, we go directly to
 		#the next step
-		obj.step_threshold=.7*ones(obj.nsteps) #30 per cent decrement
+		self.step_threshold=.7*ones(self.nsteps) #30 per cent decrement
 
 		#stop control solution at the gradient computation and return it? 
-		obj.gradient_only=0
+		self.gradient_only=0
 
 		#cost_function_threshold is a criteria to stop the control methods.
 		#if J[n]-J[n-1]/J[n] < criteria, the control run stops
 		#NaN if not applied
-		obj.cost_function_threshold=NaN #not activated 
+		self.cost_function_threshold=NaN #not activated 
 
-		return obj
-		#}}}
+		return self
+	#}}}
 
+	def checkconsistency(self,md,solution,analyses):    # {{{
 
+		#Early return
+		if not self.iscontrol:
+			return md
+
+		num_controls=numpy.size(md.inversion.control_parameters)
+		num_costfunc=numpy.size(md.inversion.cost_functions,1)
+
+		md = checkfield(md,'inversion.iscontrol','values',[0,1])
+		md = checkfield(md,'inversion.tao','values',[0,1])
+		md = checkfield(md,'inversion.incomplete_adjoint','values',[0,1])
+		md = checkfield(md,'inversion.control_parameters','cell',1,'values',['BalancethicknessThickeningRate','FrictionCoefficient','MaterialsRheologyBbar','Vx','Vy'])
+		md = checkfield(md,'inversion.nsteps','numel',1,'>=',1)
+		md = checkfield(md,'inversion.maxiter_per_step','size',[md.inversion.nsteps],'>=',0)
+		md = checkfield(md,'inversion.step_threshold','size',[md.inversion.nsteps])
+		md = checkfield(md,'inversion.cost_functions','size',[md.inversion.nsteps,num_costfunc],'values',[101,102,103,104,105,201,501,502,503])
+		md = checkfield(md,'inversion.cost_functions_coefficients','size',[md.mesh.numberofvertices,num_costfunc],'>=',0)
+		md = checkfield(md,'inversion.gradient_only','values',[0,1])
+		md = checkfield(md,'inversion.gradient_scaling','size',[md.inversion.nsteps,num_controls])
+		md = checkfield(md,'inversion.min_parameters','size',[md.mesh.numberofvertices,num_controls])
+		md = checkfield(md,'inversion.max_parameters','size',[md.mesh.numberofvertices,num_controls])
+
+		if solution==BalancethicknessSolutionEnum():
+			md = checkfield(md,'inversion.thickness_obs','size',[md.mesh.numberofvertices],'NaN',1)
+		else:
+			md = checkfield(md,'inversion.vx_obs','size',[md.mesh.numberofvertices],'NaN',1)
+			md = checkfield(md,'inversion.vy_obs','size',[md.mesh.numberofvertices],'NaN',1)
+
+		return md
+	# }}}
+
+	def marshall(self,fid):    # {{{
+
+		WriteData(fid,'object',self,'fieldname','iscontrol','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','tao','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','incomplete_adjoint','format','Boolean')
+		if not self.iscontrol:
+			return
+		WriteData(fid,'object',self,'fieldname','nsteps','format','Integer')
+		WriteData(fid,'object',self,'fieldname','maxiter_per_step','format','DoubleMat','mattype',3)
+		WriteData(fid,'object',self,'fieldname','cost_functions_coefficients','format','DoubleMat','mattype',1)
+		WriteData(fid,'object',self,'fieldname','gradient_scaling','format','DoubleMat','mattype',3)
+		WriteData(fid,'object',self,'fieldname','cost_function_threshold','format','Double')
+		WriteData(fid,'object',self,'fieldname','min_parameters','format','DoubleMat','mattype',3)
+		WriteData(fid,'object',self,'fieldname','max_parameters','format','DoubleMat','mattype',3)
+		WriteData(fid,'object',self,'fieldname','step_threshold','format','DoubleMat','mattype',3)
+		WriteData(fid,'object',self,'fieldname','gradient_only','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','vx_obs','format','DoubleMat','mattype',1)
+		WriteData(fid,'object',self,'fieldname','vy_obs','format','DoubleMat','mattype',1)
+		WriteData(fid,'object',self,'fieldname','vz_obs','format','DoubleMat','mattype',1)
+		WriteData(fid,'object',self,'fieldname','thickness_obs','format','DoubleMat','mattype',1)
+
+		#process control parameters
+		num_control_parameters=numpy.size(self.control_parameters)
+		data=[StringToEnum(self.control_parameters[i]) for i in xrange(0,num_control_parameters)]
+		WriteData(fid,'data',data,'enum',InversionControlParametersEnum(),'format','DoubleMat','mattype',3)
+		WriteData(fid,'data',num_control_parameters,'enum',InversionNumControlParametersEnum(),'format','Integer')
+
+		#process cost functions
+		num_cost_functions=size(self.cost_functions,1)
+		data=self.cost_functions
+		data[[i for i,item in enumerate(data) if item==101]]=SurfaceAbsVelMisfitEnum()
+		data[[i for i,item in enumerate(data) if item==102]]=SurfaceRelVelMisfitEnum()
+		data[[i for i,item in enumerate(data) if item==103]]=SurfaceLogVelMisfitEnum()
+		data[[i for i,item in enumerate(data) if item==104]]=SurfaceLogVxVyMisfitEnum()
+		data[[i for i,item in enumerate(data) if item==105]]=SurfaceAverageVelMisfitEnum()
+		data[[i for i,item in enumerate(data) if item==201]]=ThicknessAbsMisfitEnum()
+		data[[i for i,item in enumerate(data) if item==501]]=DragCoefficientAbsGradientEnum()
+		data[[i for i,item in enumerate(data) if item==502]]=RheologyBbarAbsGradientEnum()
+		data[[i for i,item in enumerate(data) if item==503]]=ThicknessAbsGradientEnum()
+		WriteData(fid,'data',data,'enum',InversionCostFunctionsEnum(),'format','DoubleMat','mattype',3)
+		WriteData(fid,'data',num_cost_functions,'enum',InversionNumCostFunctionsEnum(),'format','Integer')
+	# }}}
+
Index: /issm/trunk-jpl/src/m/classes/pairoptions.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/pairoptions.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/pairoptions.py	(revision 13023)
@@ -54,5 +54,5 @@
 		"""ADDFIELDDEFAULT - add a field to an options list if it does not exist"""
 		if isinstance(field,str):
-			if not field in self.list:
+			if field not in self.list:
 				self.list[field] = value
 	# }}}
Index: /issm/trunk-jpl/src/m/classes/prognostic.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/prognostic.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/prognostic.py	(revision 13023)
@@ -59,5 +59,5 @@
 
 		#Early return
-		if (not PrognosticAnalysisEnum() in analyses) or (solution==TransientSolutionEnum() and not md.transient.isprognostic):
+		if (PrognosticAnalysisEnum() not in analyses) or (solution==TransientSolutionEnum() and not md.transient.isprognostic):
 			return md
 
Index: /issm/trunk-jpl/src/m/classes/steadystate.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/steadystate.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/steadystate.py	(revision 13023)
@@ -1,6 +1,17 @@
 #module imports
+import numpy
 from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import *
+from WriteData import *
 
 class steadystate(object):
+	"""
+	STEADYSTATE class definition
+
+	   Usage:
+	      steadystate=steadystate();
+	"""
+
 	#properties
 	def __init__(self):
@@ -14,23 +25,44 @@
 
 		#}}}
-	def __repr__(obj):
+	def __repr__(self):
 		# {{{ Display
 		string='   steadystate solution parameters:'
-		string="%s\n%s"%(string,fielddisplay(obj,'reltol','relative tolerance criterion'))
-		string="%s\n%s"%(string,fielddisplay(obj,'maxiter','maximum number of iterations'))
-		string="%s\n%s"%(string,fielddisplay(obj,'requested_outputs','additional requested outputs'))
+		string="%s\n%s"%(string,fielddisplay(self,'reltol','relative tolerance criterion'))
+		string="%s\n%s"%(string,fielddisplay(self,'maxiter','maximum number of iterations'))
+		string="%s\n%s"%(string,fielddisplay(self,'requested_outputs','additional requested outputs'))
 		return string
 		#}}}
 		
-	def setdefaultparameters(obj):
+	def setdefaultparameters(self):
 		# {{{setdefaultparameters
 		
 		#maximum of steady state iterations
-		obj.maxiter=100
+		self.maxiter=100
 
 		#Relative tolerance for the steadystate convertgence
-		obj.reltol=0.01
+		self.reltol=0.01
 
-		return obj
+		return self
 	#}}}
 
+	def checkconsistency(self,md,solution,analyses):    # {{{
+
+		#Early return
+		if not solution==SteadystateSolutionEnum():
+			return md
+
+		if not md.timestepping.time_step==0:
+			md.checkmessage("for a steadystate computation, timestepping.time_step must be zero.")
+
+		if numpy.isnan(md.diagnostic.reltol):
+			md.checkmessage("for a steadystate computation, diagnostic.reltol (relative convergence criterion) must be defined!")
+
+		return md
+	# }}}
+
+	def marshall(self,fid):    # {{{
+		WriteData(fid,'object',self,'fieldname','reltol','format','Double')
+		WriteData(fid,'object',self,'fieldname','maxiter','format','Integer')
+		WriteData(fid,'object',self,'fieldname','requested_outputs','format','DoubleMat','mattype',3)
+	# }}}
+
Index: /issm/trunk-jpl/src/m/classes/thermal.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/thermal.m	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/thermal.m	(revision 13023)
@@ -48,6 +48,6 @@
 			md = checkfield(md,'thermal.spctemperature','forcing',1);
 			if (ismember(EnthalpyAnalysisEnum(),analyses) & md.thermal.isenthalpy & md.mesh.dimension==3),
-			md = checkfield(md,'thermal.spctemperature','<',md.materials.meltingpoint-md.materials.beta*md.materials.rho_ice*md.constants.g*(md.geometry.surface-md.mesh.z),'message','spctemperature should be below the adjusted melting point');
-			md = checkfield(md,'thermal.isenthalpy','numel',1,'values',[0 1]);
+				md = checkfield(md,'thermal.spctemperature','<',md.materials.meltingpoint-md.materials.beta*md.materials.rho_ice*md.constants.g*(md.geometry.surface-md.mesh.z),'message','spctemperature should be below the adjusted melting point');
+				md = checkfield(md,'thermal.isenthalpy','numel',1,'values',[0 1]);
 			end
 		end % }}}
Index: /issm/trunk-jpl/src/m/classes/thermal.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/thermal.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/thermal.py	(revision 13023)
@@ -1,6 +1,16 @@
 #module imports
 from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import *
+from WriteData import *
 
 class thermal(object):
+	"""
+	THERMAL class definition
+
+	   Usage:
+	      thermal=thermal();
+	"""
+
 	#properties
 	def __init__(self):
@@ -18,35 +28,60 @@
 
 		#}}}
-	def __repr__(obj):
+	def __repr__(self):
 		# {{{ Display
 		string='   Thermal solution parameters:'
-		string="%s\n\n%s"%(string,fielddisplay(obj,'spctemperature','temperature constraints (NaN means no constraint)'))
-		string="%s\n%s"%(string,fielddisplay(obj,'stabilization','0->no, 1->artificial_diffusivity, 2->SUPG'))
-		string="%s\n%s"%(string,fielddisplay(obj,'maxiter','maximum number of non linear iterations'))
-		string="%s\n%s"%(string,fielddisplay(obj,'penalty_lock','stabilize unstable thermal constraints that keep zigzagging after n iteration (default is 0, no stabilization)'))
-		string="%s\n%s"%(string,fielddisplay(obj,'penalty_threshold','threshold to declare convergence of thermal solution (default is 0)'))
-		string="%s\n%s"%(string,fielddisplay(obj,'isenthalpy','use an enthalpy formulation to include temperate ice (default is 0)'))
+		string="%s\n\n%s"%(string,fielddisplay(self,'spctemperature','temperature constraints (NaN means no constraint)'))
+		string="%s\n%s"%(string,fielddisplay(self,'stabilization','0->no, 1->artificial_diffusivity, 2->SUPG'))
+		string="%s\n%s"%(string,fielddisplay(self,'maxiter','maximum number of non linear iterations'))
+		string="%s\n%s"%(string,fielddisplay(self,'penalty_lock','stabilize unstable thermal constraints that keep zigzagging after n iteration (default is 0, no stabilization)'))
+		string="%s\n%s"%(string,fielddisplay(self,'penalty_threshold','threshold to declare convergence of thermal solution (default is 0)'))
+		string="%s\n%s"%(string,fielddisplay(self,'isenthalpy','use an enthalpy formulation to include temperate ice (default is 0)'))
 		return string
 		#}}}
 		
-	def setdefaultparameters(obj):
+	def setdefaultparameters(self):
 		# {{{setdefaultparameters
 		
 		#Number of unstable constraints acceptable
-		obj.penalty_threshold=0
+		self.penalty_threshold=0
 
 		#Type of stabilization used
-		obj.stabilization=1
+		self.stabilization=1
 
 		#Maximum number of iterations
-		obj.maxiter=100
+		self.maxiter=100
 
 		#factor used to compute the values of the penalties: kappa=max(stiffness matrix)*10^penalty_factor
-		obj.penalty_factor=3
+		self.penalty_factor=3
 
 		#Should we use cold ice (default) or enthalpy formulation
-		obj.isenthalpy=0
+		self.isenthalpy=0
 
-		return obj
+		return self
 	#}}}
 
+	def checkconsistency(self,md,solution,analyses):    # {{{
+
+		#Early return
+		if (ThermalAnalysisEnum() not in analyses and EnthalpyAnalysisEnum() not in analyses) or (solution==TransientSolutionEnum() and not md.transient.isthermal):
+			return md
+
+		md = checkfield(md,'thermal.stabilization','numel',1,'values',[0,1,2])
+		md = checkfield(md,'thermal.spctemperature','forcing',1)
+		if EnthalpyAnalysisEnum() in analyses and md.thermal.isenthalpy and md.mesh.dimension==3:
+			md = checkfield(md,'thermal.spctemperature','<',md.materials.meltingpoint-md.materials.beta*md.materials.rho_ice*md.constants.g*(md.geometry.surface-md.mesh.z),'message',"spctemperature should be below the adjusted melting point")
+			md = checkfield(md,'thermal.isenthalpy','numel',1,'values',[0,1])
+
+		return md
+	# }}}
+
+	def marshall(self,fid):    # {{{
+		WriteData(fid,'object',self,'fieldname','spctemperature','format','DoubleMat','mattype',1)
+		WriteData(fid,'object',self,'fieldname','penalty_threshold','format','Integer')
+		WriteData(fid,'object',self,'fieldname','stabilization','format','Integer')
+		WriteData(fid,'object',self,'fieldname','maxiter','format','Integer')
+		WriteData(fid,'object',self,'fieldname','penalty_lock','format','Integer')
+		WriteData(fid,'object',self,'fieldname','penalty_factor','format','Double')
+		WriteData(fid,'object',self,'fieldname','isenthalpy','format','Boolean')
+	# }}}
+
Index: /issm/trunk-jpl/src/m/classes/transient.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/transient.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/classes/transient.py	(revision 13023)
@@ -1,6 +1,16 @@
 #module imports
 from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import *
+from WriteData import *
 
 class transient(object):
+	"""
+	TRANSIENT class definition
+
+	   Usage:
+	      transient=transient();
+	"""
+
 	#properties
 	def __init__(self):
@@ -16,25 +26,49 @@
 
 		#}}}
-	def __repr__(obj):
+	def __repr__(self):
 		# {{{ Display
 		string='   transient solution parameters:'
-		string="%s\n%s"%(string,fielddisplay(obj,'isprognostic','indicates if a prognostic solution is used in the transient'))
-		string="%s\n%s"%(string,fielddisplay(obj,'isthermal','indicates if a thermal solution is used in the transient'))
-		string="%s\n%s"%(string,fielddisplay(obj,'isdiagnostic','indicates if a diagnostic solution is used in the transient'))
-		string="%s\n%s"%(string,fielddisplay(obj,'isgroundingline','indicates if a groundingline migration is used in the transient'))
-		string="%s\n%s"%(string,fielddisplay(obj,'requested_outputs','list of additional outputs requested'))
+		string="%s\n%s"%(string,fielddisplay(self,'isprognostic','indicates if a prognostic solution is used in the transient'))
+		string="%s\n%s"%(string,fielddisplay(self,'isthermal','indicates if a thermal solution is used in the transient'))
+		string="%s\n%s"%(string,fielddisplay(self,'isdiagnostic','indicates if a diagnostic solution is used in the transient'))
+		string="%s\n%s"%(string,fielddisplay(self,'isgroundingline','indicates if a groundingline migration is used in the transient'))
+		string="%s\n%s"%(string,fielddisplay(self,'requested_outputs','list of additional outputs requested'))
 		return string
 		#}}}
 		
-	def setdefaultparameters(obj):
+	def setdefaultparameters(self):
 		# {{{setdefaultparameters
 		
 		#full analysis: Diagnostic, Prognostic and Thermal but no groundingline migration for now
-		obj.isprognostic=1
-		obj.isdiagnostic=1
-		obj.isthermal=1
-		obj.isgroundingline=0
+		self.isprognostic=1
+		self.isdiagnostic=1
+		self.isthermal=1
+		self.isgroundingline=0
 
-		return obj
+		return self
 	#}}}
 
+	def checkconsistency(self,md,solution,analyses):    # {{{
+
+		#Early return
+		if not solution==TransientSolutionEnum():
+			return md
+
+		md = checkfield(md,'transient.isprognostic','numel',1,'values',[0,1])
+		md = checkfield(md,'transient.isdiagnostic','numel',1,'values',[0,1])
+		md = checkfield(md,'transient.isthermal','numel',1,'values',[0,1])
+		md = checkfield(md,'transient.isgroundingline','numel',1,'values',[0,1])
+		md = checkfield(md,'transient.requested_outputs','size',[float('NaN')])
+
+
+		return md
+	# }}}
+
+	def marshall(self,fid):    # {{{
+		WriteData(fid,'object',self,'fieldname','isprognostic','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','isdiagnostic','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','isthermal','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','isgroundingline','format','Boolean')
+		WriteData(fid,'object',self,'fieldname','requested_outputs','format','DoubleMat','mattype',3)
+	# }}}
+
Index: /issm/trunk-jpl/src/m/consistency/checkfield.py
===================================================================
--- /issm/trunk-jpl/src/m/consistency/checkfield.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/consistency/checkfield.py	(revision 13023)
@@ -50,5 +50,7 @@
 		fieldsize=options.getfieldvalue('size')
 		if   len(fieldsize) == 1:
-			if (not numpy.size(field,0)==fieldsize[0]):
+			if   numpy.isnan(fieldsize[0]):
+				pass
+			elif not numpy.size(field,0)==fieldsize[0]:
 				md = md.checkmessage(options.getfieldvalue('message',\
 					"field '%s' size should be %d" % (fieldname,fieldsize[0])))
@@ -70,5 +72,5 @@
 	if options.exist('numel'):
 		fieldnumel=options.getfieldvalue('numel')
-		if not numpy.size(field) in fieldnumel:
+		if numpy.size(field) not in fieldnumel:
 			if   len(fieldnumel)==1:
 				md = md.checkmessage(options.getfieldvalue('message',\
Index: /issm/trunk-jpl/src/m/os/issmdir.py
===================================================================
--- /issm/trunk-jpl/src/m/os/issmdir.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/os/issmdir.py	(revision 13023)
@@ -11,5 +11,5 @@
 	"""
 
-	if not 'Windows' in platform.system():
+	if 'Windows' not in platform.system():
 		ISSM_DIR =os.environ['ISSM_DIR']
 	else:
Index: /issm/trunk-jpl/src/m/solve/MatlabProcessPatch.py
===================================================================
--- /issm/trunk-jpl/src/m/solve/MatlabProcessPatch.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/solve/MatlabProcessPatch.py	(revision 13023)
@@ -11,5 +11,5 @@
 
 		#return if there is no field Patch
-		if not 'Patch' in structurei:
+		if 'Patch' not in structurei:
 			continue
 
Index: /issm/trunk-jpl/src/m/solve/loadresultsfromcluster.py
===================================================================
--- /issm/trunk-jpl/src/m/solve/loadresultsfromcluster.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/solve/loadresultsfromcluster.py	(revision 13023)
@@ -41,5 +41,5 @@
 		os.remove(md.miscellaneous.name+'.errlog')
 		os.remove(md.miscellaneous.name+'.outbin')
-		if not 'Windows' in platform.system():
+		if 'Windows' not in platform.system():
 			os.remove(md.private.runtimename+'.tar.gz')
 
@@ -53,5 +53,5 @@
 			os.remove(md.miscellaneous.name+'.bin')
 			os.remove(md.miscellaneous.name+'.petsc')
-			if not 'Windows' in platform.system():
+			if 'Windows' not in platform.system():
 				os.remove(md.miscellaneous.name+'.queue')
 			else:
Index: /issm/trunk-jpl/src/m/solve/parseresultsfromdisk.py
===================================================================
--- /issm/trunk-jpl/src/m/solve/parseresultsfromdisk.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/solve/parseresultsfromdisk.py	(revision 13023)
@@ -42,5 +42,5 @@
 	while result:
 		#Get time and step
-		if not result['step'] in results:
+		if result['step'] not in results:
 			results[result['step']]={}
 			results[result['step']]['step']=result['step']
@@ -85,5 +85,5 @@
 
 		#Get time and step
-		if not result['step'] in results:
+		if result['step'] not in results:
 			results[result['step']]={}
 			results[result['step']]['step']=result['step']
@@ -124,5 +124,5 @@
 
 		#Get time and step
-		if not result['step'] in results:
+		if result['step'] not in results:
 			results[result['step']]={}
 			results[result['step']]['step']=result['step']
Index: /issm/trunk-jpl/src/m/solve/process_solve_options.py
===================================================================
--- /issm/trunk-jpl/src/m/solve/process_solve_options.py	(revision 13022)
+++ /issm/trunk-jpl/src/m/solve/process_solve_options.py	(revision 13023)
@@ -16,5 +16,5 @@
 	#solution_type: check on this option, error out otherwise
 	solution_type=options.getfieldvalue('solution_type')
-	if not solution_type in (DiagnosticSolutionEnum,PrognosticSolutionEnum,ThermalSolutionEnum,\
+	if solution_type not in (DiagnosticSolutionEnum,PrognosticSolutionEnum,ThermalSolutionEnum,\
 			SteadystateSolutionEnum,TransientSolutionEnum,EnthalpySolutionEnum,\
 			BalancethicknessSolutionEnum,BedSlopeSolutionEnum,SurfaceSlopeSolutionEnum,HydrologySolutionEnum,FlaimSolutionEnum):
