#module imports
import numpy
import copy
from fielddisplay import fielddisplay
from EnumDefinitions import *
from checkfield import *
from WriteData import *

class flowequation(object):
	"""
	FLOWEQUATION class definition

	   Usage:
	      flowequation=flowequation();
	"""

	#properties
	def __init__(self):
		# {{{ Properties
		
		self.ismacayealpattyn     = 0;
		self.ishutter             = 0;
		self.isl1l2             = 0;
		self.isstokes             = 0;
		self.vertex_equation      = float('NaN')
		self.element_equation     = float('NaN')
		self.bordermacayeal       = float('NaN')
		self.borderpattyn         = float('NaN')
		self.borderstokes         = float('NaN')

		#set defaults
		self.setdefaultparameters()

		#}}}
	def __repr__(self):
		# {{{ Display
		string='   flow equation parameters:'

		string="%s\n\n%s"%(string,fielddisplay(self,'ismacayealpattyn','is the macayeal or pattyn approximation used ?'))
		string="%s\n%s"%(string,fielddisplay(self,'ishutter','is the shallow ice approximation used ?'))
		string="%s\n%s"%(string,fielddisplay(self,'isl1l2','are l1l2 equations used ?'))
		string="%s\n%s"%(string,fielddisplay(self,'isstokes','are the Full-Stokes equations used ?'))
		string="%s\n%s"%(string,fielddisplay(self,'vertex_equation','flow equation for each vertex'))
		string="%s\n%s"%(string,fielddisplay(self,'element_equation','flow equation for each element'))
		string="%s\n%s"%(string,fielddisplay(self,'bordermacayeal','vertices on MacAyeal''s border (for tiling)'))
		string="%s\n%s"%(string,fielddisplay(self,'borderpattyn','vertices on Pattyn''s border (for tiling)'))
		string="%s\n%s"%(string,fielddisplay(self,'borderstokes','vertices on Stokes'' border (for tiling)'))
		return string
		#}}}
		
	def setdefaultparameters(self):
		# {{{setdefaultparameters
		return self
	#}}}

	def checkconsistency(self,md,solution,analyses):    # {{{

		if DiagnosticHorizAnalysisEnum() in analyses:
			md = checkfield(md,'flowequation.ismacayealpattyn','numel',[1],'values',[0,1])
			md = checkfield(md,'flowequation.ishutter','numel',[1],'values',[0,1])
			md = checkfield(md,'flowequation.isl1l2','numel',[1],'values',[0,1])
			md = checkfield(md,'flowequation.isstokes','numel',[1],'values',[0,1])
			md = checkfield(md,'flowequation.bordermacayeal','size',[md.mesh.numberofvertices],'values',[0,1])
			md = checkfield(md,'flowequation.borderpattyn','size',[md.mesh.numberofvertices],'values',[0,1])
			md = checkfield(md,'flowequation.borderstokes','size',[md.mesh.numberofvertices],'values',[0,1])
			if md.mesh.dimension==2:
				md = checkfield(md,'flowequation.vertex_equation','size',[md.mesh.numberofvertices],'values',[1,2])
				md = checkfield(md,'flowequation.element_equation','size',[md.mesh.numberofelements],'values',[1,2])
			else:
				md = checkfield(md,'flowequation.vertex_equation','size',[md.mesh.numberofvertices],'values',numpy.arange(0,7+1))
				md = checkfield(md,'flowequation.element_equation','size',[md.mesh.numberofelements],'values',numpy.arange(0,7+1))
			if not (self.ismacayealpattyn or self.ishutter or self.isstokes or self.isl1l2):
				md.checkmessage("no element types set for this model. At least one of ismacayealpattyn, ishutter or isstokes need to be =1")

		if DiagnosticHutterAnalysisEnum() in analyses:
			if any(self.element_equation==1):
				if numpy.any(numpy.logical_and(self.element_equation,md.mask.elementonfloatingice)):
					print "\n !!! Warning: Hutter's model is not consistent on ice shelves !!!\n"

		return md
	# }}}

	def marshall(self,fid):    # {{{
		WriteData(fid,'object',self,'fieldname','ismacayealpattyn','format','Boolean')
		WriteData(fid,'object',self,'fieldname','ishutter','format','Boolean')
		WriteData(fid,'object',self,'fieldname','isl1l2','format','Boolean')
		WriteData(fid,'object',self,'fieldname','isstokes','format','Boolean')
		WriteData(fid,'object',self,'fieldname','bordermacayeal','format','DoubleMat','mattype',1)
		WriteData(fid,'object',self,'fieldname','borderpattyn','format','DoubleMat','mattype',1)
		WriteData(fid,'object',self,'fieldname','borderstokes','format','DoubleMat','mattype',1)
		#convert approximations to enums
		data=copy.deepcopy(self.vertex_equation)
		data[numpy.nonzero(data==0)]=NoneApproximationEnum()
		data[numpy.nonzero(data==1)]=HutterApproximationEnum()
		data[numpy.nonzero(data==2)]=MacAyealApproximationEnum()
		data[numpy.nonzero(data==3)]=PattynApproximationEnum()
		data[numpy.nonzero(data==4)]=StokesApproximationEnum()
		data[numpy.nonzero(data==5)]=MacAyealPattynApproximationEnum()
		data[numpy.nonzero(data==6)]=MacAyealStokesApproximationEnum()
		data[numpy.nonzero(data==7)]=PattynStokesApproximationEnum()
		data[numpy.nonzero(data==8)]=L1L2ApproximationEnum()
		WriteData(fid,'data',data,'enum',FlowequationVertexEquationEnum(),'format','DoubleMat','mattype',1)
		data=copy.deepcopy(self.element_equation)
		data[numpy.nonzero(data==0)]=NoneApproximationEnum()
		data[numpy.nonzero(data==1)]=HutterApproximationEnum()
		data[numpy.nonzero(data==2)]=MacAyealApproximationEnum()
		data[numpy.nonzero(data==3)]=PattynApproximationEnum()
		data[numpy.nonzero(data==4)]=StokesApproximationEnum()
		data[numpy.nonzero(data==5)]=MacAyealPattynApproximationEnum()
		data[numpy.nonzero(data==6)]=MacAyealStokesApproximationEnum()
		data[numpy.nonzero(data==7)]=PattynStokesApproximationEnum()
		data[numpy.nonzero(data==8)]=L1L2ApproximationEnum()
		WriteData(fid,'data',data,'enum',FlowequationElementEquationEnum(),'format','DoubleMat','mattype',2)
	# }}}

