//SLR class definition
//
//   Usage:
//      slr=slr();

function slr(){
	//methods
		this.setdefaultparameters = function (){ //{{{
		
		//Convergence criterion: absolute, relative and residual
		this.reltol=NaN; //default
		this.abstol=0.001; //1 mm of sea level rise

		//maximum of non-linear iterations.
		this.maxiter=10;

		//computational flags: 
		this.rigid=1;
		this.elastic=1;
		this.rotation=0;
		this.ocean_area_scaling=0;
		
		//tidal love numbers: 
		this.tide_love_h=0.6149; //degree 2
		this.tide_love_k=0.3055; //degree 2
	
		// mean rotational velocity of earth:
		this.angular_velocity=7.2921*10^-5; // [s^-1] 

		//numerical discretization accuracy
		this.degacc=.01;
		
		//output default:
		this.requested_outputs=['default'];

		//transitions should be a cell array of vectors: 
		this.transitions=[];
		
		}// }}}
		this.checkconsistency = function(md,solution,analyses) { //{{{

			//Early return
			if(ArrayAnyEqual(ArrayIsMember('SealevelriseAnalysis',analyses),0))return;
			
			md = checkfield(md,'fieldname','slr.deltathickness','NaN',1,'Inf',1,'size',[md.mesh.numberofelements, 1]);
			md = checkfield(md,'fieldname','slr.sealevel','NaN',1,'Inf',1,'size',[md.mesh.numberofvertices, 1]);
			md = checkfield(md,'fieldname','slr.love_h','NaN',1,'Inf',1);
			md = checkfield(md,'fieldname','slr.love_k','NaN',1,'Inf',1);
			md = checkfield(md,'fieldname','slr.love_l','NaN',1,'Inf',1);
			md = checkfield(md,'fieldname','slr.tide_love_h','NaN',1,'Inf',1);
			md = checkfield(md,'fieldname','slr.tide_love_k','NaN',1,'Inf',1);
			md = checkfield(md,'fieldname','slr.angular_velocity','NaN',1,'Inf',1);
			md = checkfield(md,'fieldname','slr.reltol','size',[1, 1]);
			md = checkfield(md,'fieldname','slr.abstol','size',[1, 1]);
			md = checkfield(md,'fieldname','slr.maxiter','size',[1, 1],'>=',1);
			md = checkfield(md,'fieldname','slr.degacc','size',[1, 1],'>=',1e-10);
			md = checkfield(md,'fieldname','slr.requested_outputs','stringrow',1);
			
			//check that love numbers are provided at the same level of accuracy: 
			if (this.love_h.length != this.love_k.length || this.love_h.length != this.love_l.length){
				throw Error('slr error message: love numbers should be provided at the same level of accuracy');
			}

		} // }}}
		this.defaultoutputs = function(md){ // {{{
			return ['Sealevel'];
		}//}}}
		this.classname= function(){// {{{
			return "slr";
		}// }}}
		this.disp= function(){// {{{
			
		console.log(sprintf('   Sealevelrise solution parameters:'));

		fielddisplay(this,'deltathickness','thickness change (main loading of the slr solution core [m]');
		fielddisplay(this,'sealevel','current sea level (prior to computation) [m]');
		fielddisplay(this,'reltol','sea level rise relative convergence criterion, (default, NaN: not applied)');
		fielddisplay(this,'abstol','sea level rise absolute convergence criterion, NaN: not applied');
		fielddisplay(this,'maxiter','maximum number of nonlinear iterations');
		fielddisplay(this,'love_h','load Love number for radial displacement');
		fielddisplay(this,'love_k','load Love number for gravitational potential perturbation');
		fielddisplay(this,'love_l','load Love number for horizontal displacements'); 
		fielddisplay(this,'tide_love_h','tidal love number (degree 2)');
		fielddisplay(this,'tide_love_k','tidal love number (degree 2)');
		fielddisplay(this,'angular_velocity','mean rotational velocity of earth [per second]'); 
		fielddisplay(this,'rigid','rigid earth graviational potential perturbation');
		fielddisplay(this,'elastic','elastic earth graviational potential perturbation');
		fielddisplay(this,'rotation','rotational earth potential perturbation');
		fielddisplay(this,'ocean_area_scaling','correction for model representation of ocean area [default: No correction]'); 
		fielddisplay(this,'degacc',"accuracy (default .01 deg) for numerical discretization of the Green's functions");
		fielddisplay(this,'transitions','indices into parts of the mesh that will be icecaps');
		fielddisplay(this,'requested_outputs','additional outputs requested');
		} //}}}
		this.marshall=function(md,prefix,fid) { //{{{

			WriteData(fid,prefix,'object',this,'fieldname','deltathickness','format','DoubleMat','mattype',2);
			WriteData(fid,prefix,'object',this,'fieldname','sealevel','mattype',1,'format','DoubleMat','timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts);
			WriteData(fid,prefix,'object',this,'fieldname','reltol','format','Double');
			WriteData(fid,prefix,'object',this,'fieldname','abstol','format','Double');
			WriteData(fid,prefix,'object',this,'fieldname','maxiter','format','Integer');
			WriteData(fid,prefix,'object',this,'fieldname','love_h','format','DoubleMat','mattype',1);
			WriteData(fid,prefix,'object',this,'fieldname','love_k','format','DoubleMat','mattype',1);
			WriteData(fid,prefix,'object',this,'fieldname','love_l','format','DoubleMat','mattype',1);
			WriteData(fid,prefix,'object',this,'fieldname','tide_love_h','format','Double');
			WriteData(fid,prefix,'object',this,'fieldname','tide_love_k','format','Double');
			WriteData(fid,prefix,'object',this,'fieldname','angular_velocity','format','Double');
			WriteData(fid,prefix,'object',this,'fieldname','rigid','format','Boolean');
			WriteData(fid,prefix,'object',this,'fieldname','elastic','format','Boolean');
			WriteData(fid,prefix,'object',this,'fieldname','rotation','format','Boolean');
			WriteData(fid,prefix,'object',this,'fieldname','ocean_area_scaling','format','Boolean');
			WriteData(fid,prefix,'object',this,'fieldname','degacc','format','Double');
			WriteData(fid,prefix,'object',this,'fieldname','transitions','format','MatArray');

			//process requested outputs
			var outputs = this.requested_outputs;
			for (var i=0;i<outputs.length;i++){
				if (outputs[i] == 'default') {
					outputs.splice(i,1);
					var newoutputs=this.defaultoutputs(md);
					for (var j=0;j<newoutputs.length;j++) outputs.push(newoutputs[j]);
				}
			}
			WriteData(fid,prefix,'data',outputs,'name','md.slr.requested_outputs','format','StringArray');
		}//}}}
		this.fix=function() { //{{{
			this.deltathickness=NullFix(this.deltathickness,NaN);
			this.sealevel=NullFix(this.sealevel,NaN);
			this.maxiter=NullFix(this.maxiter,NaN);
			this.reltol=NullFix(this.reltol,NaN);
			this.abstol=NullFix(this.abstol,NaN);
			this.love_h=NullFix(this.love_h,NaN);
			this.love_k=NullFix(this.love_k,NaN);
			this.love_l=NullFix(this.love_l,NaN);
			this.tide_love_h=NullFix(this.tide_love_h,NaN);
			this.tide_love_k=NullFix(this.tide_love_k,NaN);
			this.angular_velocity=NullFix(this.angular_velocity,NaN);
			this.rigid=NullFix(this.rigid,NaN);
			this.elastic=NullFix(this.elastic,NaN);
			this.rotation=NullFix(this.rotation,NaN);
			this.ocean_area_scaling=NullFix(this.ocean_area_scaling,NaN);
			this.degacc=NullFix(this.degacc,NaN);
		}//}}}
	//properties
	//{{{
	this.deltathickness = NaN;
	this.sealevel       = NaN; 
	this.maxiter        = 0;
	this.reltol         = 0;
	this.abstol         = 0;
	this.love_h         = 0; //provided by PREM model
	this.love_k         = 0; //idam
	this.love_l         = 0; //idam
	this.tide_love_h    = 0; 
	this.tide_love_k    = 0; 
	this.angular_velocity = 0; 
	this.rigid          = 0;
	this.elastic        = 0;
	this.rotation       = 0;
	this.ocean_area_scaling = 0;
	this.degacc         = 0;
	this.requested_outputs = [];
	this.transitions    = [];
	this.setdefaultparameters();
	//}}}
}
