#module imports
from fielddisplay import fielddisplay

class diagnostic:
	#properties
	def __init__(self):
		# {{{ Properties
		self.spcvx                    = float('NaN')
		self.spcvy                    = float('NaN')
		self.spcvz                    = float('NaN')
		self.restol                   = 0
		self.reltol                   = 0
		self.abstol                   = 0
		self.isnewton                 = 0
		self.stokesreconditioning     = 0
		self.viscosity_overshoot      = 0
		self.icefront                 = float('NaN')
		self.maxiter                  = 0
		self.shelf_dampening          = 0
		self.vertex_pairing           = float('NaN')
		self.penalty_factor           = float('NaN')
		self.rift_penalty_lock        = float('NaN')
		self.rift_penalty_threshold   = 0
		self.referential              = float('NaN')
		self.requested_outputs        = float('NaN')

		#set defaults
		self.setdefaultparameters()

		#}}}
	def __repr__(obj):
		# {{{ Display
		
		
		string='\n   Diagnostic solution parameters:'
		string="%s\n\n%s"%(string,'      Convergence criteria:')
			
		string="%s\n%s"%(string,fielddisplay(obj,'restol','mechanical equilibrium residual convergence criterion'))
		string="%s\n%s"%(string,fielddisplay(obj,'reltol','velocity relative convergence criterion, NaN -> not applied'))
		string="%s\n%s"%(string,fielddisplay(obj,'abstol','velocity absolute convergence criterion, NaN -> not applied'))
		string="%s\n%s"%(string,fielddisplay(obj,'isnewton','Apply Newton''s method instead of a Picard fixed point method'))
		string="%s\n%s"%(string,fielddisplay(obj,'maxiter','maximum number of nonlinear iterations'))
		string="%s\n%s"%(string,fielddisplay(obj,'viscosity_overshoot','over-shooting constant new=new+C*(new-old)'))

		string="%s\n%s"%(string,'      boundary conditions:')

		string="%s\n%s"%(string,fielddisplay(obj,'spcvx','x-axis velocity constraint (NaN means no constraint)'))
		string="%s\n%s"%(string,fielddisplay(obj,'spcvy','y-axis velocity constraint (NaN means no constraint)'))
		string="%s\n%s"%(string,fielddisplay(obj,'spcvz','z-axis velocity constraint (NaN means no constraint)'))
		string="%s\n%s"%(string,fielddisplay(obj,'icefront','segments on ice front list (last column 0-> Air, 1-> Water, 2->Ice'))

		string="%s\n%s"%(string,'      Rift options:')
		string="%s\n%s"%(string,fielddisplay(obj,'rift_penalty_threshold','threshold for instability of mechanical constraints'))
		string="%s\n%s"%(string,fielddisplay(obj,'rift_penalty_lock','number of iterations before rift penalties are locked'))

		string="%s\n%s"%(string,'      Penalty options:')
		string="%s\n%s"%(string,fielddisplay(obj,'penalty_factor','offset used by penalties: penalty = Kmax*10^offset'))
		string="%s\n%s"%(string,fielddisplay(obj,'vertex_pairing','pairs of vertices that are penalized'))

		string="%s\n%s"%(string,'      Other:')
		string="%s\n%s"%(string,fielddisplay(obj,'shelf_dampening','use dampening for floating ice ? Only for Stokes model'))
		string="%s\n%s"%(string,fielddisplay(obj,'stokesreconditioning','multiplier for incompressibility equation. Only for Stokes model'))
		string="%s\n%s"%(string,fielddisplay(obj,'referential','local referential'))
		string="%s\n%s"%(string,fielddisplay(obj,'requested_outputs','additional outputs requested'))

		return string
		#}}}
		
	def setdefaultparameters(obj):
		# {{{setdefaultparameters
		#maximum of non-linear iterations.
		obj.maxiter=100

		#Convergence criterion: absolute, relative and residual
		obj.restol=10**-4;
		obj.reltol=0.01
		obj.abstol=10

		obj.stokesreconditioning=10**13
		obj.shelf_dampening=0

		#Penalty factor applied kappa=max(stiffness matrix)*10^penalty_factor
		obj.penalty_factor=3

		#coefficient to update the viscosity between each iteration of
		#a diagnostic according to the following formula
		#viscosity(n)=viscosity(n)+viscosity_overshoot(viscosity(n)-viscosity(n-1))
		obj.viscosity_overshoot=0

		#Stop the iterations of rift if below a threshold
		obj.rift_penalty_threshold=0

		#in some solutions, it might be needed to stop a run when only
		#a few constraints remain unstable. For thermal computation, this
		#parameter is often used.
		obj.rift_penalty_lock=10

		return obj
	#}}}
