Index: /issm/trunk/src/m/model/BasinConstrain.m
===================================================================
--- /issm/trunk/src/m/model/BasinConstrain.m	(revision 5901)
+++ /issm/trunk/src/m/model/BasinConstrain.m	(revision 5901)
@@ -0,0 +1,65 @@
+function md=BasinConstrain(md,domain);
+%BASINCONSTRAIN - constrain basin
+%
+%   Constrain basin using a constraint domain outline, 
+%   to dirichlet boundary conditions.
+%   constraindomain is an Argus domain outline file enclosing 
+%   the geographical area of interest.
+%
+%   Usage: 
+%      md=BasinConstrain(md,constraindomain)
+%
+%   Example:
+%      md=BasinConstrain(md,'DomainOutline.exp');
+%      md=BasinConstrain(md,'~Iceshelves.exp');
+
+%now, flag grids and elements outside the domain outline.
+if ischar(domain),
+	if isempty(domain),
+		elementondomain=zeros(md.numberofelements,1);
+		gridondomain=zeros(md.numberofgrids,1);
+		invert=0;
+	elseif strcmpi(domain,'all')
+		elementondomain=ones(md.numberofelements,1);
+		gridondomain=ones(md.numberofgrids,1);
+		invert=0;
+	else
+		%make sure that we actually don't want the elements outside the domain outline!
+		if strcmpi(domain(1),'~'),
+			domain=domain(2:end);
+			invert=1;
+		else
+			invert=0;
+		end
+		%ok, flag elements and nodes
+		[gridondomain elementondomain]=ContourToMesh(md.elements(:,1:3),md.x,md.y,domain,'element and node',2);
+	end
+	if invert,
+		gridondomain=~gridondomain;
+		elementondomain=~elementondomain;
+	end
+else
+	error('BasinConstrain error message: domain type not supported yet');
+end
+
+%list of elements and nodes not on domain
+gridnotondomain=find(~gridondomain);
+elementnotondomain=find(~elementondomain);
+
+%all elements outside the constraint domain are equivalent to water. all grids outside are spc'd.
+md.spcvelocity(gridnotondomain,1:2)=1;
+md.spcvelocity(gridnotondomain,4)=md.vx_obs(gridnotondomain);
+md.spcvelocity(gridnotondomain,5)=md.vy_obs(gridnotondomain);
+md.elementonwater(elementnotondomain)=1;
+
+%now, make sure all elements on water have grids that are spc'd, otherwise, we'll get a singular problem.
+pos=find(~md.elementonwater);
+numpos=unique(md.elements(pos,:));
+grids=setdiff(1:1:md.numberofgrids,numpos);
+md.spcvelocity(grids,1:2)=1;
+md.spcvelocity(grids,4)=md.vx_obs(grids);
+md.spcvelocity(grids,5)=md.vy_obs(grids);
+
+%make sure icefronts that are completely spc'd are taken out:
+free_segments=find(sum(md.spcvelocity(md.pressureload(:,1:2),1:2),2)~=2);
+md.pressureload=md.pressureload(free_segments,:);
Index: /issm/trunk/src/m/model/BasinConstrain2.m
===================================================================
--- /issm/trunk/src/m/model/BasinConstrain2.m	(revision 5901)
+++ /issm/trunk/src/m/model/BasinConstrain2.m	(revision 5901)
@@ -0,0 +1,66 @@
+function md=BasinConstrain2(md,domain);
+%BASINCONSTRAIN - constrain basin
+%
+%   Constrain basin using a constraint domain outline, 
+%   to dirichlet boundary conditions.
+%   constraindomain is an Argus domain outline file enclosing 
+%   the geographical area of interest.
+%
+%   Usage: 
+%      md=BasinConstrain(md,constraindomain)
+%
+%   Example:
+%      md=BasinConstrain(md,'DomainOutline.exp');
+%      md=BasinConstrain(md,'~Iceshelves.exp');
+
+%now, flag grids and elements outside the domain outline.
+if ischar(domain),
+	if isempty(domain),
+		elementondomain=zeros(md.numberofelements,1);
+		gridondomain=zeros(md.numberofgrids,1);
+		invert=0;
+	elseif strcmpi(domain,'all')
+		elementondomain=ones(md.numberofelements,1);
+		gridondomain=ones(md.numberofgrids,1);
+		invert=0;
+	else
+		%make sure that we actually don't want the elements outside the domain outline!
+		if strcmpi(domain(1),'~'),
+			domain=domain(2:end);
+			invert=1;
+		else
+			invert=0;
+		end
+		%ok, flag elements and nodes
+		[gridondomain elementondomain]=ContourToMesh(md.elements(:,1:3),md.x,md.y,domain,'element and node',2);
+	end
+	if invert,
+		gridondomain=~gridondomain;
+		elementondomain=~elementondomain;
+	end
+else
+	error('BasinConstrain error message: domain type not supported yet');
+end
+
+%list of elements and nodes not on domain
+gridnotondomain=find(~gridondomain);
+elementnotondomain=find(~elementondomain);
+
+%all elements outside the constraint domain are equivalent to water. all grids outside are spc'd.
+md.spcvelocity(gridnotondomain,1:2)=1;
+md.spcvelocity(gridnotondomain,4)=md.vx_obs(gridnotondomain);
+md.spcvelocity(gridnotondomain,5)=md.vy_obs(gridnotondomain);
+md.elementonwater(elementnotondomain)=1;
+
+%now, make sure all elements on water have grids that are spc'd, otherwise, we'll get a singular problem.
+pos=find(~md.elementonwater);
+numpos=unique(md.elements(pos,:));
+grids=setdiff(1:1:md.numberofgrids,numpos);
+md.spcvelocity(grids,1:2)=1;
+md.spcvelocity(grids,4)=md.vx_obs(grids);
+md.spcvelocity(grids,5)=md.vy_obs(grids);
+
+
+%make sure icefronts that are completely spc'd are taken out:
+free_segments=find(sum(md.spcvelocity(md.pressureload(:,1:2),1:2),2)~=2);
+md.pressureload=md.pressureload(free_segments,:);
Index: /issm/trunk/src/m/model/BasinConstrainShelf.m
===================================================================
--- /issm/trunk/src/m/model/BasinConstrainShelf.m	(revision 5901)
+++ /issm/trunk/src/m/model/BasinConstrainShelf.m	(revision 5901)
@@ -0,0 +1,79 @@
+function md=BasinConstrainShelf(md,domain);
+%BASINCONSTRAIN - constrain basin
+%
+%   Constrain basin using a constraint domain outline, 
+%   to dirichlet boundary conditions.
+%   constraindomain is an Argus domain outline file enclosing 
+%   the geographical area of interest.
+%
+%   Usage: 
+%      md=BasinConstrain(md,constraindomain)
+%
+%   Example:
+%      md=BasinConstrain(md,'DomainOutline.exp');
+%      md=BasinConstrain(md,'~Iceshelves.exp');
+
+%now, flag grids and elements outside the domain outline.
+if ischar(domain),
+	if isempty(domain),
+		elementondomain=zeros(md.numberofelements,1);
+		gridondomain=zeros(md.numberofgrids,1);
+		invert=0;
+	elseif strcmpi(domain,'all')
+		elementondomain=ones(md.numberofelements,1);
+		gridondomain=ones(md.numberofgrids,1);
+		invert=0;
+	else
+		%make sure that we actually don't want the elements outside the domain outline!
+		if strcmpi(domain(1),'~'),
+			domain=domain(2:end);
+			invert=1;
+		else
+			invert=0;
+		end
+		%ok, flag elements and nodes
+		[gridondomain elementondomain]=ContourToMesh(md.elements(:,1:3),md.x,md.y,domain,'element and node',2);
+	end
+	if invert,
+		gridondomain=~gridondomain;
+		elementondomain=~elementondomain;
+	end
+else
+	error('BasinConstrain error message: domain type not supported yet');
+end
+
+%list of elements and nodes not on domain
+gridnotondomain=find(~gridondomain);
+elementnotondomain=find(~elementondomain);
+
+%all elements outside the constraint domain are equivalent to water. all grids outside are spc'd.
+md.spcvelocity(gridnotondomain,1:2)=1;
+md.spcvelocity(gridnotondomain,4)=md.vx_obs(gridnotondomain);
+md.spcvelocity(gridnotondomain,5)=md.vy_obs(gridnotondomain);
+md.elementonwater(elementnotondomain)=1;
+
+%now, make sure all elements on water have grids that are spc'd, otherwise, we'll get a singular problem.
+pos=find(~md.elementonwater);
+numpos=unique(md.elements(pos,:));
+grids=setdiff(1:1:md.numberofgrids,numpos);
+md.spcvelocity(grids,1:2)=1;
+md.spcvelocity(grids,4)=md.vx_obs(grids);
+md.spcvelocity(grids,5)=md.vy_obs(grids);
+
+
+%make sure any grid with NaN velocity is spc'd:
+pos=find(isnan(md.vel_obs_raw));
+md.spcvelocity(pos,1:2)=1;
+%we spc to the smoothed value, so that control methods don't go berserk trying to figure out what reaction force to apply for the spc to stand.
+md.spcvelocity(pos,4)=md.vx_obs(pos); 
+md.spcvelocity(pos,5)=md.vy_obs(pos); 
+
+%iceshelves: any grid on icesheet is spc'd
+pos=find(md.gridonicesheet);
+md.spcvelocity(pos,1:2)=1;
+md.spcvelocity(pos,4)=md.vx_obs(pos); 
+md.spcvelocity(pos,5)=md.vy_obs(pos); 
+
+%make sure icefronts that are completely spc'd are taken out:
+free_segments=find(sum(md.spcvelocity(md.pressureload(:,1:2),1:2),2)~=2);
+md.pressureload=md.pressureload(free_segments,:);
Index: /issm/trunk/src/m/model/DepthAverage.m
===================================================================
--- /issm/trunk/src/m/model/DepthAverage.m	(revision 5901)
+++ /issm/trunk/src/m/model/DepthAverage.m	(revision 5901)
@@ -0,0 +1,33 @@
+function  vector_average=DepthAverage(md,vector);
+%DEPTHAVERAGE - computes depth average of 3d vector, and return value on 2d mesh. 
+%
+%   Usage:
+%      vector_average=DepthAverage(md,vector);
+%
+%   Example:
+%      vel_bar=DepthAverage(md,md.vel);
+
+%check that the model given in input is 3d
+if ~md.dim==3;
+	error('DepthAverage error message: the model given in input must be 3d')
+end
+
+%nods data
+if (length(vector)==md.numberofgrids),
+	vector_average=zeros(md.numberofgrids2d,1);
+	for i=1:md.numlayers-1,
+		vector_average=vector_average+(project2d(md,vector,i)+project2d(md,vector,i+1))/2.*(project2d(md,md.z,i+1)-project2d(md,md.z,i));
+	end
+	vector_average=vector_average./project2d(md,md.thickness,1);
+
+%element data
+elseif (length(vector)==md.numberofelements),
+	vector_average=zeros(md.numberofelements2d,1);
+	for i=1:md.numlayers-1,
+		vector_average=vector_average+project2d(md,vector,i).*(project2d(md,md.z,i+1)-project2d(md,md.z,i));
+	end
+	vector_average=vector_average./project2d(md,md.thickness,1);
+
+else
+	error('vector size not supported yet');
+end
Index: /issm/trunk/src/m/model/MeltingGroundingLines.m
===================================================================
--- /issm/trunk/src/m/model/MeltingGroundingLines.m	(revision 5901)
+++ /issm/trunk/src/m/model/MeltingGroundingLines.m	(revision 5901)
@@ -0,0 +1,26 @@
+function md=MeltingGroundingLines(md,distance,value)
+%MELTINGGROUNDINGLINES - set melting near grounding lines to a constant value
+%
+%   Usage:
+%      md=MeltingGroundingLines(md,distance,value)
+%
+
+%get nodes on ice sheet and on ice shelf
+pos_shelf=find(~md.gridonicesheet);
+pos_GL=intersect(unique(md.elements(find(md.elementonicesheet),:)),unique(md.elements(find(md.elementoniceshelf),:)));
+
+for i=1:length(pos_shelf)
+
+	if (mod(i,100)==0),
+		fprintf('\b\b\b\b\b\b\b%5.2f%s',i/length(pos_shelf)*100,' %');
+	end
+
+	%search the grid on ice sheet the closest to i
+	[d posd]=min(sqrt((md.x(pos_shelf(i))-md.x(pos_GL)).^2+(md.y(pos_shelf(i))-md.y(pos_GL)).^2));
+
+	if d<distance,
+
+		md.melting(pos_shelf(i))=value;
+
+	end
+end
Index: /issm/trunk/src/m/model/PropagateFlagsUntilDistance.m
===================================================================
--- /issm/trunk/src/m/model/PropagateFlagsUntilDistance.m	(revision 5901)
+++ /issm/trunk/src/m/model/PropagateFlagsUntilDistance.m	(revision 5901)
@@ -0,0 +1,64 @@
+function new_flags=PropagateFlagsUntilDistance(md,flags,distance)
+%PROPAGATEFLAGSUNTILDISTANCE
+%
+% Usage: 
+%              flags=PropagateFlagsUntilDistance(md,flags,distance)
+%
+%
+
+
+	
+new_flags=flags;
+
+%make 3d work in 2d: 
+if md.dim==3,
+	md.x=md.x2d;
+	md.y=md.y2d;
+	md.elements=md.elements2d;
+end
+
+%find elements that are at the border of flags: 
+flag_elements=find(flags);
+conn=md.elementconnectivity(flag_elements,:);
+pos=find(conn);conn(pos)=~flags(conn(pos));
+sum_conn=sum(conn,2);
+border_elements=flag_elements(find(sum_conn>=1));
+
+
+%average x and y over elements: 
+x_elem=md.x(md.elements)*[1;1;1]/3;
+y_elem=md.y(md.elements)*[1;1;1]/3;
+
+while 1,
+
+	%keep copy of new_flags for this loop: 
+	new_flags_bak=new_flags;
+
+	%extend new flags by connectivity
+	pos=find(new_flags);
+
+	connected_elements=md.elementconnectivity(pos,:);
+	connected_elements=connected_elements(find(connected_elements));
+	new_flags(connected_elements)=1;
+
+	%get new elements: 
+	new_elements=find(new_flags & ~new_flags_bak);
+	if ~length(new_elements),
+		%we are done!
+		break;
+	end
+
+
+	%check which of these new elements are more than distance away from the border elements
+	for i=1:length(new_elements),
+		dist=sqrt(     (x_elem(border_elements)-x_elem(new_elements(i))).^2 + (y_elem(border_elements)-y_elem(new_elements(i))).^2)-distance;
+		if ~any(dist<0)
+			%none of the border elements are within distance, this element is outside out area of interest.
+			%ensure this element never gets found again in the connectivity.
+			pos=find(md.elementconnectivity==new_elements(i));
+			md.elementconnectivity(pos)=0;
+			%exclude this new element from the new_flags!
+			new_flags(new_elements(i))=0;
+		end
+	end
+end
Index: /issm/trunk/src/m/model/QueueJobPeek.m
===================================================================
--- /issm/trunk/src/m/model/QueueJobPeek.m	(revision 5901)
+++ /issm/trunk/src/m/model/QueueJobPeek.m	(revision 5901)
@@ -0,0 +1,15 @@
+function md=QueueJobPeek(md,executionpath)
+%QUEUEJOBPEEK - ...
+%
+%   Usage:
+%      QueueJobPeek(md,executionpath)
+
+%First try and figure out if there is a special script for thie particular cluster
+function_name=['QueueJobPeek' md.cluster];
+if exist(function_name,'file'),
+	%Call this function:
+	eval(['md=' function_name '(md,executionpath);']);
+else
+	%Call the generic QueueJobPeek:
+	md=QueueJobPeekGeneric(md,executionpath);
+end
Index: /issm/trunk/src/m/model/QueueJobPeekGeneric.m
===================================================================
--- /issm/trunk/src/m/model/QueueJobPeekGeneric.m	(revision 5901)
+++ /issm/trunk/src/m/model/QueueJobPeekGeneric.m	(revision 5901)
@@ -0,0 +1,27 @@
+function md=QueueJobPeekGeneric(md,executionpath)
+%QUEUEJOBPEEKGENERIC - ...
+%
+%   Usage:
+%      md=QueueJobPeekGeneric(md,executionpath)
+
+disp('downloading error and output log files');
+
+%download errlog and outlog from cluster
+system(['scp ' md.cluster ':' executionpath '/' md.name '.*log ./']);
+
+%read log files onto  fields
+md.errlog=char(textread([md.name '.errlog'],'%s','delimiter','\n'));
+md.outlog=char(textread([md.name '.outlog'],'%s','delimiter','\n'));
+
+%cat those two files
+disp(sprintf('\n\nerror log:\n\n'));
+system(['cat ' md.name '.errlog']);
+
+disp(sprintf('\n\noutput log:\n\n'));
+system(['cat ' md.name '.outlog']);
+
+%erase the log files
+system(['rm -rf ' md.name '.outlog ' md.name '.errlog']);
+
+%warn user
+disp(sprintf('\n\nerror and output logs are saved in model fields for further checking'));
Index: /issm/trunk/src/m/model/README
===================================================================
--- /issm/trunk/src/m/model/README	(revision 5901)
+++ /issm/trunk/src/m/model/README	(revision 5901)
@@ -0,0 +1,11 @@
+This directory is similar to @model, in that it only deals
+with methods proper to the @model class. But we need a different 
+directory from @model, to make those methods public, not private. 
+The advantage of public methods is that they will use subsref and 
+susasgn to access data in a @model object.
+
+For ex: 
+calling md.x in a "@model" routine just accesses the x field in the md 
+structure. But calling md.x in a "model" routine will access the x field 
+through the susref routine in @model. This ensures that we protect the 
+data in @model classes from improper use.
Index: /issm/trunk/src/m/model/ReadData.m
===================================================================
--- /issm/trunk/src/m/model/ReadData.m	(revision 5901)
+++ /issm/trunk/src/m/model/ReadData.m	(revision 5901)
@@ -0,0 +1,38 @@
+function result=ReadData(fid)
+%READDATA - ...
+%
+%   Usage:
+%      field=ReadData(fid)
+
+
+%read field
+[length,count]=fread(fid,1,'int');
+
+if count==0,
+	result=struct([]);
+else
+	fieldname=fread(fid,length,'char');
+	fieldname=fieldname(1:end-1)';
+	fieldname=char(fieldname);
+	time=fread(fid,1,'double');
+	step=fread(fid,1,'int');
+
+	type=fread(fid,1,'int');
+	M=fread(fid,1,'int');
+	if type==1,
+		field=fread(fid,M,'double');
+	elseif type==2,
+		field=fread(fid,M,'char');
+		field=char(field(1:end-1)');
+	elseif type==3,
+		N=fread(fid,1,'int');
+		field=transpose(fread(fid,[N M],'double'));
+	else
+		error(['cannot read data of type ' num2str(type) ]);
+	end
+
+	result.fieldname=fieldname;
+	result.time=time;
+	result.step=step;
+	result.field=field;
+end
Index: /issm/trunk/src/m/model/SectionValues.m
===================================================================
--- /issm/trunk/src/m/model/SectionValues.m	(revision 5901)
+++ /issm/trunk/src/m/model/SectionValues.m	(revision 5901)
@@ -0,0 +1,125 @@
+function [index,X,Y,Z,S,data_interp]=SectionValues(md,data,infile,resolution)
+%SECTIONVALUES - compute the value of a field on a section
+%
+%   This routine gets the value of a given field of the model on points
+%   given by filname (Argus type file)
+%
+%   Usage:
+%      [elements,x,y,z,s,data]=SectionValues(md,data,filename,resolution)
+%      [elements,x,y,z,s,data]=SectionValues(md,data,profile_structure,resolution)
+
+%check what we have for profile as input
+if ischar(infile),
+	%read infile:
+	contempt=expread(infile,1);
+	nods=contempt.nods;
+	x=contempt.x;
+	y=contempt.y;
+else
+	%read infile:
+	nods=infile.nods;
+	x=infile.x;
+	y=infile.y;
+end
+
+
+%get the specified resolution
+if isnumeric(resolution(1))
+	res_h=resolution(1);
+else
+	error('SectionValues error message: wrong resolution type. Resolution must be an array [horizontal_resolution vertical_resolution]')
+end
+if md.dim==3
+	if (length(resolution)==2 & isnumeric(resolution(2)))
+		res_v=resolution(2);
+	else
+		error('SectionValues error message: wrong resolution type. Resolution must be an array [horizontal_resolution vertical_resolution]')
+	end
+end
+
+%initialization
+X=[]; %X-coordinate
+Y=[]; %Y-coordinate
+S=0;  %curvilinear coordinate
+
+for i=1:nods-1
+
+	x_start=x(i);
+	x_end=x(i+1);
+	y_start=y(i);
+	y_end=y(i+1);
+	s_start=S(end);
+
+	length_segment=sqrt((x_end-x_start)^2+(y_end-y_start)^2);
+	portion=ceil(length_segment/res_h);
+
+	x_segment=zeros(portion,1);
+	y_segment=zeros(portion,1);
+	s_segment=zeros(portion,1);
+
+	for j=1:portion
+		x_segment(j)=x_start+(j-1)*(x_end-x_start)/portion;
+		y_segment(j)=y_start+(j-1)*(y_end-y_start)/portion;
+		s_segment(j)=s_start+j*length_segment/portion;
+	end
+
+	%plug into X and Y
+	X=[X;x_segment];
+	Y=[Y;y_segment];
+	S=[S;s_segment];
+end
+X(end+1)=x(nods);
+Y(end+1)=y(nods);
+
+%Number of grids:
+numberofgrids=size(X,1);
+
+%Compute Z
+Z=zeros(numberofgrids,1);
+
+%New mesh and Data interpolation
+if (md.dim==2)
+
+	%Interpolation of data on specified points
+	data_interp=InterpFromMeshToMesh2d(md.elements,md.x,md.y,data,X,Y);
+
+	%Compute index
+	index=[1:1:(numberofgrids-1);2:1:numberofgrids]';
+
+else
+
+	%vertically extrude mesh
+
+	%Get bed and surface for each 2d point, offset to make sure that it is inside the glacier system
+	offset=10^-3;
+	bed=InterpFromMeshToMesh2d(md.elements2d,md.x2d,md.y2d,project2d(md,md.bed,1),X,Y)+offset;
+	surface=InterpFromMeshToMesh2d(md.elements2d,md.x2d,md.y2d,project2d(md,md.surface,1),X,Y)-offset;
+
+	%Some useful parameters
+	layers=ceil(mean(md.thickness)/res_v);
+	gridsperlayer=numberofgrids;
+	gridstot=gridsperlayer*layers;
+	elementsperlayer=gridsperlayer-1;
+	elementstot=(gridsperlayer-1)*(layers-1);
+
+	%initialization
+	X3=zeros(gridsperlayer*layers,1); Y3=zeros(gridsperlayer*layers,1); Z3=zeros(gridsperlayer*layers,1); S3=zeros(gridsperlayer*layers,1); index3=zeros(elementstot,4);
+
+	%Get new coordinates in 3d
+	for i=1:layers
+		X3(i:layers:end)=X;
+		Y3(i:layers:end)=Y;
+		Z3(i:layers:end)=bed+(i-1)*(surface-bed)/(layers-1);
+		S3(i:layers:end)=S;
+
+		if i<layers %Build index3 with quads
+			index3((i-1)*elementsperlayer+1:i*elementsperlayer,:)=[i:layers:gridstot-layers; i+1:layers:gridstot-layers; i+layers+1:layers:gridstot; i+layers:layers:gridstot]';
+		end
+	end
+
+	%Interpolation of data on specified points
+	data_interp=InterpFromMeshToMesh3d(md.elements,md.x,md.y,md.z,data,X3,Y3,Z3,NaN);
+
+	%build outputs
+	X=X3; Y=Y3; Z=Z3;  S=S3; index=index3;
+end
Index: /issm/trunk/src/m/model/ThicknessCorrection.m
===================================================================
--- /issm/trunk/src/m/model/ThicknessCorrection.m	(revision 5901)
+++ /issm/trunk/src/m/model/ThicknessCorrection.m	(revision 5901)
@@ -0,0 +1,73 @@
+function md=ThicknessCorrection(md,varargin)
+%THICKNESSCORRECTION - correct the thickness of the ice shelf near the grounding line
+%
+%   This routine corrects the thickness and the bed on the transition zone
+%   by forcing the hydrostatic equilibrium.
+%   the thickness is modified as follows:
+%      thickness = coeff * thickness_observation + (1-coeff) * thickness_hydrostatic
+%   where:
+%      coeff=(d/distance)^2;
+%      distance=10km by default but can be specified
+%
+%   Usage:
+%      md=ThicknessCorrection(md,varargin);
+%
+%   Example:
+%      md=ThicknessCorrection(md);
+%      md=ThicknessCorrection(md,15000);
+
+%initialize thickness with the observations, and get hydrostatic thickness from the dem
+thickness=md.thickness;
+thickness_hydro=md.surface/(1-md.rho_ice/md.rho_water);
+
+%get nodes on ice sheet and on ice shelf
+pos_shelf=find(~md.gridonicesheet);
+pos_GL=intersect(unique(md.elements(find(md.elementonicesheet),:)),unique(md.elements(find(md.elementoniceshelf),:)));
+debug=(length(pos_shelf)>50000);
+
+%check that there is a GL
+if isempty(pos_GL)
+	error('ThicknessCorrection error message: no grounding line has been detected. Check the model geography');
+end
+
+%get distance
+if nargin==2,
+	distance=varargin{1};
+else
+	distance=10000;
+end
+
+%modify thickness
+if (debug), fprintf('%s','      correction progress:   0.00 %'); end
+for i=1:length(pos_shelf)
+
+	if (debug & mod(i,100)==0),
+		fprintf('\b\b\b\b\b\b\b%5.2f%s',i/length(pos_shelf)*100,' %');
+	end
+
+	%search the grid on ice sheet the closest to i
+	[d posd]=min(sqrt((md.x(pos_shelf(i))-md.x(pos_GL)).^2+(md.y(pos_shelf(i))-md.y(pos_GL)).^2));
+
+	if d>distance,
+
+		%if d > 15km, hydrostatique equilibrium
+		thickness(pos_shelf(i))=thickness_hydro(pos_shelf(i));
+
+	else
+
+		%else: quadratic combination of hydrostatic equilibrium and observations
+		coeff=(d/distance)^2;
+		thickness(pos_shelf(i))=(1-coeff)*thickness(pos_shelf(i))+coeff*thickness_hydro(pos_shelf(i));
+
+	end
+end
+if (debug), fprintf('\b\b\b\b\b\b\b%5.2f%s\n',100,' %'); end
+
+%check the computed thickness
+minth=1/(1-md.rho_ice/md.rho_water);
+pos=find(isnan(md.thickness) | (md.thickness<=0));
+thickness(pos)=minth;
+
+%change bed to take into account the changes in thickness
+md.thickness=thickness;
+md.bed=md.surface-md.thickness;
Index: /issm/trunk/src/m/model/WriteData.m
===================================================================
--- /issm/trunk/src/m/model/WriteData.m	(revision 5901)
+++ /issm/trunk/src/m/model/WriteData.m	(revision 5901)
@@ -0,0 +1,50 @@
+function WriteData(fid,data,data_type,name)
+%WRITEDATA - ...
+%
+%   Usage:
+%      WriteData(fid,data,data_type)
+
+if issparse(data),
+	data=full(data);
+end
+
+%Ok! put the length of the name, and the "name" string first!
+fwrite(fid,length(name),'int'); 
+fwrite(fid,name,'char'); 
+
+if strcmpi(data_type,'String'),
+	%first write length of record
+	fwrite(fid,length(data)+4,'int');  %4 for int32
+	%now write string
+	fwrite(fid,length(data),'int'); 
+	fwrite(fid,data,'char'); 
+elseif strcmpi(data_type,'Mat'),
+	%Get size
+	s=size(data);
+	%if matrix = NaN, then do not write anything
+	if (s(1)==1 & s(2)==1 & isnan(data)),
+		s(1)=0; s(2)=0;
+	end
+	
+	%first write length of record
+	fwrite(fid,4+4+8*s(1)*s(2),'int');  %2 integers (32 bits) + the double matrix
+
+	%now write matrix
+	fwrite(fid,s(1),'int'); 
+	fwrite(fid,s(2),'int'); 
+	if s(1)*s(2),
+		fwrite(fid,data','double'); %get to the "c" convention, hence the transpose
+	end
+elseif strcmpi(data_type,'Integer'),
+	%first write length of record
+	fwrite(fid,4,'int');  %1 integer
+	%now write integer
+	fwrite(fid,data,'int'); 
+elseif strcmpi(data_type,'Scalar'),
+	%first write length of record
+	fwrite(fid,8,'int');  %1 double
+	%now write double
+	fwrite(fid,data,'double'); 
+else 
+	error('WriteData error message: data type not supported yet!');
+end
Index: /issm/trunk/src/m/model/addnote.m
===================================================================
--- /issm/trunk/src/m/model/addnote.m	(revision 5901)
+++ /issm/trunk/src/m/model/addnote.m	(revision 5901)
@@ -0,0 +1,36 @@
+function md=addnote(md,string)
+%ADDNOTE - add a note to the existing model notes field
+%
+%   Usage:
+%      md=addnote(md,string);
+%
+%   Example:
+%      md=addnote(md,'Pine Island, Geometry of 2007');
+
+if (nargin~=2) & (nargout~=1),
+	addnoteusage;
+	error(' ');
+end
+
+if ~ischar(string),
+	error('addnote error message: second input argument should be a string');
+end
+notes=md.notes;
+
+if ischar(notes),
+	newnotes=cell(2,1);
+	newnotes(1)={notes};
+	newnotes(2)={string};
+else
+	newnotes=cell(length(notes)+1,1);
+	for i=1:length(notes),
+		newnotes(i)=notes(i);
+	end
+	newnotes(length(notes)+1)={string};
+end
+
+md.notes=newnotes;
+
+function addnoteusage()
+disp('addnote usage:');
+disp('   model=addnote(model,string)');
Index: /issm/trunk/src/m/model/averageconnectivity.m
===================================================================
--- /issm/trunk/src/m/model/averageconnectivity.m	(revision 5901)
+++ /issm/trunk/src/m/model/averageconnectivity.m	(revision 5901)
@@ -0,0 +1,11 @@
+function conn=averageconnectivity(md)
+%AVERAGECONNECTIVITY - computes the average connectivity of a model
+%
+%   Usage:
+%      connectivity=averageconnectivity(md);
+
+nnz=0;
+for i=1:md.numberofgrids,
+	nnz=nnz+length(find(md.elements==i));
+end
+conn=nnz/md.numberofgrids;
Index: /issm/trunk/src/m/model/averaging.m
===================================================================
--- /issm/trunk/src/m/model/averaging.m	(revision 5901)
+++ /issm/trunk/src/m/model/averaging.m	(revision 5901)
@@ -0,0 +1,62 @@
+function average=averaging(md,data,iterations)
+%AVERAGING - smooths the input over the mesh
+%
+%   This routine takes a list over the elements or the grids in input
+%   and return a list over the grids.
+%   For each iterations it computes the average over each element (average 
+%   of the vertices values) and then computes the average over each grid
+%   by taking the average of the element around a grid weighted by the
+%   elements volume
+%
+%   Usage:
+%      smoothdata=averaging(md,data,iterations)
+%
+%   Examples:
+%      velsmoothed=averaging(md,md.vel,4);
+%      pressure=averaging(md,md.pressure,0);
+
+if length(data)~=md.numberofelements & length(data)~=md.numberofgrids
+	error('averaging error message: data not supported yet');
+end
+
+%initialization
+weights=zeros(md.numberofgrids,1);
+data=data(:);
+
+%load some variables (it is much faster if the variab;es are loaded from md once for all)
+index=md.elements;
+numberofgrids=md.numberofgrids;
+numberofelements=md.numberofelements;
+
+%build some variables
+line=index(:);
+if md.dim==3
+	rep=6;
+	areas=GetAreas(index,md.x,md.y,md.z);
+else
+	rep=3;
+	areas=GetAreas(index,md.x,md.y);
+end
+summation=1/rep*ones(rep,1);
+linesize=rep*numberofelements;
+
+%update weights that holds the volume of all the element holding the grid i
+weights=sparse(line,ones(linesize,1),repmat(areas,rep,1),numberofgrids,1);
+
+%initialization
+if length(data)==numberofelements
+	average_grid=sparse(line,ones(linesize,1),repmat(areas.*data,rep,1),numberofgrids,1);
+	average_grid=average_grid./weights;
+else
+	average_grid=data;
+end
+
+%loop over iteration
+for i=1:iterations
+	average_el=average_grid(index)*summation;
+	average_grid=sparse(line,ones(linesize,1),repmat(areas.*average_el,rep,1),numberofgrids,1);
+	average_grid=average_grid./weights;
+end
+
+%return output as a full matrix (C code do not like sparse matrices)
+average=full(average_grid);
Index: /issm/trunk/src/m/model/balvel.m
===================================================================
--- /issm/trunk/src/m/model/balvel.m	(revision 5901)
+++ /issm/trunk/src/m/model/balvel.m	(revision 5901)
@@ -0,0 +1,26 @@
+function [velx,vely,vel]=balvel(md)
+%BALVEL - computation of balanced velocities
+%
+%   This routine uses the model of Hutter to compute the velocities
+%   of a 2d model using the surface slope
+%
+%   Usage:
+%      [velx,vely,vel]=balvel(md)
+
+if md.dim~=2,
+	error('Only 2d meshes are allowed to compute velocity balances');
+end
+
+%Get slope
+[sx,sy,s]=slope(md);
+
+%Average thickness and B over all elements.
+summer=[1;1;1];
+hel=md.thickness(md.elements)*summer/3;
+Bel=md.B(md.elements)*summer/3;
+
+Ael=Bel.^(-3);
+
+velx=-2*(md.rho_ice*md.g)^3*s.^2.*sx.*Ael/4.*hel.^4;
+vely=-2*(md.rho_ice*md.g)^3*s.^2.*sy.*Ael/4.*hel.^4;
+vel=sqrt(velx.^2+vely.^2);
Index: /issm/trunk/src/m/model/bamg.m
===================================================================
--- /issm/trunk/src/m/model/bamg.m	(revision 5901)
+++ /issm/trunk/src/m/model/bamg.m	(revision 5901)
@@ -0,0 +1,345 @@
+function md=bamg(md,varargin)
+%BAMG - mesh generation
+%
+%   Available options (for more details see ISSM website http://issm.jpl.nasa.gov/):
+%
+%   - domain: followed by an ARGUS file that prescribes the domain outline
+%   - hmin  : minimum edge length (default is 10^-100)
+%   - hmax  : maximum esge length (default is 10^100)
+%   - hVertices   : imposed edge length for each vertex (geometry or mesh)
+%   - hminVertices: minimum edge length for each vertex (mesh)
+%   - hmaxVertices: maximum edge length for each vertex (mesh)
+%   - prescribedVertices:  vertices that should be kept by bamg. [x,y,marker]; marker is optional
+%
+%   - anisomax    : maximum ration between the smallest and largest edges (default is 10^30)
+%   - coeff       : coefficient applied to the metric (2-> twice as many elements, default is 1)
+%   - cutoff      : scalar used to compute the metric when metric type 2 or 3 are applied
+%   - err         : error used to generate the metric from a field
+%   - errg        : geometrical error (default is 0.1)
+%   - field       : field of the model that will be used to compute the metric
+%                   to apply several fields, use one column per field
+%   - gradation   : maximum ration between two adjacent edges
+%   - Hessiantype : 0 -> use double P2 projection (default)
+%                   1 -> use Green formula
+%   - KeepVertices: try to keep initial vertices when adaptation is done on an existing mesh (default 1)
+%   - MaxCornerAngle: maximal angle of corners in degree (default is 10)
+%   - maxnbv      : maximum number of vertices used to allocate memory (default is 10^6)
+%   - maxsubdiv   : maximum subdivision of exisiting elements (default is 10)
+%   - metric      : matrix (numberofgrids x 3) used as a metric
+%   - Metrictype  : 1 -> absolute error          c/(err coeff^2) * Abs(H)        (default)
+%                   2 -> relative error          c/(err coeff^2) * Abs(H)/max(s,cutoff*max(s))
+%                   3 -> rescaled absolute error c/(err coeff^2) * Abs(H)/(smax-smin)
+%   - nbjacoby    : correction used by Hessiantype=1 (default is 1)
+%   - nbsmooth    : number of metric smoothing procedure (default is 3)
+%   - omega       : relaxation parameter of the smoothing procedure (default is 1.8)
+%   - power       : power applied to the metric (default is 1)
+%   - splitcorners : split triangles whuch have 3 vertices on the outline (default is 1)
+%   - geometricalmetric : Take the geometry into account to generate the metric (default is 0)
+%   - verbose     : level of verbosity (default is 1)
+%
+%   - rifts : followed by an ARGUS file that prescribes the rifts
+%   - toltip: tolerance to move tip on an existing point of the domain outline
+%   - tracks: followed by an ARGUS file that prescribes the tracks that the mesh will stick to
+%   - tol:    if the distance between 2 points of the domain outline is less than tol, they
+%             will be merged
+%
+%   Examples:
+%      md=bamg(md,'domain','DomainOutline.exp','hmax',3000);
+%      md=bamg(md,'field',[md.vel_obs md.thickness],'hmax',20000,'hmin',1000);
+%      md=bamg(md,'metric',A,'hmin',1000,'hmax',20000,'gradation',3,'anisomax',1);
+
+%process options
+options=pairoptions(varargin{:});
+options=deleteduplicates(options,1);
+
+%initialize the structures required as input of Bamg
+bamg_options=struct();
+bamg_geometry=bamggeom;
+bamg_mesh=bamgmesh;
+
+% Bamg Geometry parameters {{{1
+if exist(options,'domain'),
+
+	%Check that file exists
+	domainfile=getfieldvalue(options,'domain');
+	if ~exist(domainfile,'file') error(['bamg error message: file ' domainfile ' not found ']); end
+
+	%Build geometry 
+	domain=expread(domainfile);
+	count=0;
+	for i=1:length(domain),
+
+		%Check that the domain is closed
+		if (domain(i).x(1)~=domain(i).x(end) | domain(i).y(1)~=domain(i).y(end)),
+			error('bamg error message: all contours provided in ''domain'' should be closed');
+		end
+
+		%Checks that all holes are INSIDE the principle domain outline
+		if i>1,
+			flags=ContourToNodes(domain(i).x,domain(i).y,domain(1),0);
+			if any(~flags),
+				error('bamg error message: All holes should be stricly inside the principal domain');
+			end
+		end
+
+		%Add all points to bamg_geometry
+		nods=domain(i).nods-1; %the domain are closed 1=end;
+		bamg_geometry.Vertices=[bamg_geometry.Vertices; [domain(i).x(1:nods) domain(i).y(1:nods) ones(nods,1)]];
+		bamg_geometry.Edges   =[bamg_geometry.Edges;    [transpose(count+1:count+nods) transpose([count+2:count+nods count+1])  1*ones(nods,1)]];
+		if i>1, bamg_geometry.SubDomains=[bamg_geometry.SubDomains; 2 count+1 1 1]; end
+
+		%update counter
+		count=count+nods;
+	end
+
+	%take care of rifts
+	if exist(options,'rifts'),
+
+		%Check that file exists
+		riftfile=getfieldvalue(options,'rifts');
+		if ~exist(riftfile,'file')
+			error(['bamg error message: file ' riftfile ' not found ']);
+		end
+		rift=expread(riftfile);
+
+		for i=1:length(rift),
+
+			%detect wether all points of the rift are inside the domain
+			flags=ContourToNodes(rift(i).x,rift(i).y,domain(1),0);
+			if ~flags,
+				error('one Rift has all his points outside of the domain outline'),
+
+			elseif any(~flags),
+				%We LOTS of work to do
+				disp('Rift tip outside of or on the domain has been detected and is being processed...');
+
+				%check that only one point is outsie (for now)
+				if sum(~flags)~=1,
+					error('bamg error message: only one point outside of the domain is supported yet');
+				end
+
+				%Move tip outside to the first position
+				if flags(1)==0,
+					%OK, first point is outside (do nothing),
+				elseif (flags(end)==0),
+					rift(i).x=flipud(rift(i).x);
+					rift(i).y=flipud(rift(i).y);
+				else
+					error('bamg error message: only a rift tip can be outside of the domain');
+				end
+
+				%Get cordinate of intersection point
+				x1=rift(i).x(1); y1=rift(i).y(1);
+				x2=rift(i).x(2); y2=rift(i).y(2);
+				for j=1:length(domain(1).x)-1;
+					if SegIntersect([x1 y1; x2 y2],[domain(1).x(j) domain(1).y(j); domain(1).x(j+1) domain(1).y(j+1)]),
+
+						%Get position of the two nodes of the edge in domain
+						i1=j;
+						i2=mod(j+1,domain(1).nods);
+
+						%rift is crossing edge [i1 i2] of the domain
+						%Get coordinate of intersection point (http://mathworld.wolfram.com/Line-LineIntersection.html)
+						x3=domain(1).x(i1); y3=domain(1).y(i1);
+						x4=domain(1).x(i2); y4=domain(1).y(i2);
+						x=det([det([x1 y1; x2 y2])  x1-x2;det([x3 y3; x4 y4])  x3-x4])/det([x1-x2 y1-y2;x3-x4 y3-y4]);
+						y=det([det([x1 y1; x2 y2])  y1-y2;det([x3 y3; x4 y4])  y3-y4])/det([x1-x2 y1-y2;x3-x4 y3-y4]);
+
+						segdis= sqrt((x4-x3)^2+(y4-y3)^2);
+						tipdis=[sqrt((x-x3)^2+(y-y3)^2)  sqrt((x-x4)^2+(y-y4)^2)];
+
+						if (min(tipdis)/segdis) < getfieldvalue(options,'toltip',0),
+							disp('moving tip-domain intersection point');
+
+							%Get position of the closest point
+							if tipdis(1)>tipdis(2),
+								pos=i2;
+							else
+								pos=i1;
+							end
+
+							%This point is only in Vertices (number pos).
+							%OK, no we can add our own rift
+							nods=rift(i).nods-1;
+							bamg_geometry.Vertices=[bamg_geometry.Vertices; [rift(i).x(2:end) rift(i).y(2:end) ones(nods,1)]];
+							bamg_geometry.Edges=[bamg_geometry.Edges;...
+								pos count+1  (1+i);...
+								[transpose(count+1:count+nods-1) transpose([count+2:count+nods])  (1+i)*ones(nods-1,1)]];
+							count=count+nods;
+
+							break;
+
+						else
+							%Add intersection point to Vertices
+							bamg_geometry.Vertices=[bamg_geometry.Vertices; x y 1];
+							count=count+1;
+
+							%Decompose the crossing edge in 2 subedges
+							pos=find(bamg_geometry.Edges(:,1)==i1 & bamg_geometry.Edges(:,2)==i2);
+							if isempty(pos) error('bamg error message: a problem occured...'); end
+							bamg_geometry.Edges=[bamg_geometry.Edges(1:pos-1,:);...
+								bamg_geometry.Edges(pos,1) count                           bamg_geometry.Edges(pos,3);...
+								count                      bamg_geometry.Edges(pos,2)   bamg_geometry.Edges(pos,3);...
+								bamg_geometry.Edges(pos+1:end,:)];
+
+							%OK, no we can add our own rift
+							nods=rift(i).nods-1;
+							bamg_geometry.Vertices=[bamg_geometry.Vertices; [rift(i).x(2:end) rift(i).y(2:end) ones(nods,1)]];
+							bamg_geometry.Edges=[bamg_geometry.Edges;...
+								count  count+1  2 ;...
+								[transpose(count+1:count+nods-1) transpose([count+2:count+nods])  (1+i)*ones(nods-1,1)]];
+							count=count+nods;
+
+							break;
+						end
+					end
+				end
+			else
+				nods=rift(i).nods-1;
+				bamg_geometry.Vertices=[bamg_geometry.Vertices; [rift(i).x(:) rift(i).y(:) ones(nods+1,1)]];
+				bamg_geometry.Edges=[bamg_geometry.Edges; [transpose(count+1:count+nods) transpose([count+2:count+nods+1])  (1+i)*ones(nods,1)]];
+				count=count+nods+1;
+			end
+		end
+	end
+
+	%Deal with tracks
+	if exist(options,'tracks'),
+
+		%Check that file exists
+		trackfile=getfieldvalue(options,'tracks');
+		if ~exist(trackfile,'file')
+			error(['bamg error message: file ' trackfile ' not found ']);
+		end
+		track=expread(trackfile);
+
+		for i=1:length(track),
+
+			%Add all points to bamg_geometry
+			nods=track(i).nods;
+			bamg_geometry.Vertices=[bamg_geometry.Vertices; [track(i).x(1:nods) track(i).y(1:nods) 3*ones(nods,1)]];
+			bamg_geometry.Edges=[bamg_geometry.Edges; [transpose(count+1:count+nods-1) transpose([count+2:count+nods])  3*ones(nods-1,1)]];
+
+			%update counter
+			count=count+nods;
+		end
+	end
+
+	%Deal with vertices that need to be kept by mesher
+	if exist(options,'prescribedVertices'),
+
+		%recover xvertices yvertices
+		prescribedVertices=getfieldvalue(options,'prescribedVertices');
+		xvertices=prescribedVertices(:,1);
+		yvertices=prescribedVertices(:,2);
+		if(size(prescribedVertices,2)==3),
+			markers=prescribedVertices(:,3);
+		else 
+			markers=[];
+		end
+	
+		%only keep those inside
+		flags=ContourToNodes(xvertices,yvertices,domain(1),0);
+		pos=find(flags);
+		xvertices=xvertices(pos);
+		yvertices=yvertices(pos);
+		if ~isempty(markers),
+			markers=markers(pos);
+		end
+
+		%Add all points to bamg_geometry
+		nods=length(xvertices);
+		if isempty(markers),
+			markers=4*ones(nods,1);
+		end
+
+		bamg_geometry.Vertices=[bamg_geometry.Vertices; [xvertices yvertices markers]]; 
+
+	end
+
+	%process geom
+	%bamg_geometry=processgeometry(bamg_geometry,getfieldvalue(options,'tol',NaN),domain(1));
+
+elseif isstruct(md.bamg),
+
+	bamg_geometry=bamggeom(md.bamg.geometry); %TEST
+
+else
+
+	%do nothing...
+
+end
+%}}}
+
+% Bamg Mesh parameters {{{1
+if (~exist(options,'domain') & md.numberofgrids~=0 & md.dim==2),
+
+	if isstruct(md.bamg),
+		bamg_mesh=bamgmesh(md.bamg.mesh);
+	else
+		bamg_mesh.Vertices=[md.x md.y ones(md.numberofgrids,1)];
+		bamg_mesh.Triangles=[md.elements ones(md.numberofelements,1)];
+	end
+
+	if isstruct(md.rifts)
+		error('bamg error message: rifts not supported yet. Do meshprocessrift AFTER bamg');
+	end
+end
+%}}}
+
+% Bamg Options {{{1
+bamg_options.Crack=getfieldvalue(options,'Crack',0);
+bamg_options.anisomax=getfieldvalue(options,'anisomax',10^30);
+bamg_options.coeff=getfieldvalue(options,'coeff',1);
+bamg_options.cutoff=getfieldvalue(options,'cutoff',10^-5);
+bamg_options.err=getfieldvalue(options,'err',0.01);
+bamg_options.errg=getfieldvalue(options,'errg',0.1);
+bamg_options.field=getfieldvalue(options,'field',[]);
+bamg_options.gradation=getfieldvalue(options,'gradation',1.5);
+bamg_options.Hessiantype=getfieldvalue(options,'Hessiantype',0);
+bamg_options.hmin=getfieldvalue(options,'hmin',10^-100);
+bamg_options.hmax=getfieldvalue(options,'hmax',10^100);
+bamg_options.hminVertices=getfieldvalue(options,'hminVertices',[]);
+bamg_options.hmaxVertices=getfieldvalue(options,'hmaxVertices',[]);
+bamg_options.hVertices=getfieldvalue(options,'hVertices',[]);
+bamg_options.KeepVertices=getfieldvalue(options,'KeepVertices',1);
+bamg_options.MaxCornerAngle=getfieldvalue(options,'MaxCornerAngle',10);
+bamg_options.maxnbv=getfieldvalue(options,'maxnbv',10^6);
+bamg_options.maxsubdiv=getfieldvalue(options,'maxsubdiv',10);
+bamg_options.metric=getfieldvalue(options,'metric',[]);
+bamg_options.Metrictype=getfieldvalue(options,'Metrictype',0);
+bamg_options.nbjacobi=getfieldvalue(options,'nbjacobi',1);
+bamg_options.nbsmooth=getfieldvalue(options,'nbsmooth',3);
+bamg_options.omega=getfieldvalue(options,'omega',1.8);
+bamg_options.power=getfieldvalue(options,'power',1);
+bamg_options.splitcorners=getfieldvalue(options,'splitcorners',1);
+bamg_options.geometricalmetric=getfieldvalue(options,'geometricalmetric',0);
+bamg_options.verbose=getfieldvalue(options,'verbose',1);
+%}}}
+
+%call Bamg
+[bamgmesh_out bamggeom_out]=BamgMesher(bamg_mesh,bamg_geometry,bamg_options);
+
+% plug results onto model
+md.bamg=struct();
+md.bamg.mesh=bamgmesh(bamgmesh_out);
+md.bamg.geometry=bamggeom(bamggeom_out);
+md.x=bamgmesh_out.Vertices(:,1);
+md.y=bamgmesh_out.Vertices(:,2);
+md.elements=bamgmesh_out.Triangles(:,1:3);
+md.edges=bamgmesh_out.IssmEdges;
+md.segments=bamgmesh_out.IssmSegments(:,1:3);
+md.segmentmarkers=bamgmesh_out.IssmSegments(:,4);
+
+%Fill in rest of fields:
+md.dim=2;
+md.numberofelements=size(md.elements,1);
+md.numberofgrids=length(md.x);
+md.z=zeros(md.numberofgrids,1);
+md.gridonbed=ones(md.numberofgrids,1);
+md.gridonwater=zeros(md.numberofgrids,1);
+md.gridonsurface=ones(md.numberofgrids,1);
+md.elementonbed=ones(md.numberofelements,1);
+md.elementonsurface=ones(md.numberofelements,1);
+md.gridonboundary=zeros(md.numberofgrids,1); md.gridonboundary(md.segments(:,1:2))=1;
+md.counter=1;
Index: /issm/trunk/src/m/model/basalstress.m
===================================================================
--- /issm/trunk/src/m/model/basalstress.m	(revision 5901)
+++ /issm/trunk/src/m/model/basalstress.m	(revision 5901)
@@ -0,0 +1,22 @@
+function [bx by b]=basalstress(md)
+%BASALSTRESS - compute basal stress from basal drag and geometric information. 
+%
+%   Usage:
+%      [bx by b]=basalstress(md);
+%
+%   See also: plot_basaldrag
+
+
+%compute exponents
+s=averaging(md,1./md.p,0);
+r=averaging(md,md.p./md.q,0);
+
+%compute horizontal velocity
+ub=sqrt(md.vx.^2+md.vy.^2)/md.yts;
+ubx=md.vx/md.yts;
+uby=md.vy/md.yts;
+
+%compute basal drag
+bx=(md.g*(md.rho_ice*md.thickness+md.rho_water*md.bed)).^r.*(md.drag).^2.*ubx.^s;
+by=(md.g*(md.rho_ice*md.thickness+md.rho_water*md.bed)).^r.*(md.drag).^2.*uby.^s;
+b=(md.g*(md.rho_ice*md.thickness+md.rho_water*md.bed)).^r.*(md.drag).^2.*ub.^s;
Index: /issm/trunk/src/m/model/basevert.m
===================================================================
--- /issm/trunk/src/m/model/basevert.m	(revision 5901)
+++ /issm/trunk/src/m/model/basevert.m	(revision 5901)
@@ -0,0 +1,35 @@
+function wb=basevert(md)
+%BASEVERT - computes the basal vertical velcities
+%
+%   This routine computes the basal vertical velocities of ice shelves
+%   for 2d models only using the following formula:
+%   wb=rho_ice/rho_water*div(thickness*vel_horiz)+vel_horiz.grad(base)
+%
+%   Usage:
+%      wb=basevert(md);
+
+alpha=zeros(md.numberofelements,3);
+beta=zeros(md.numberofelements,3);
+gamma=zeros(md.numberofelements,3);
+
+for n=1:md.numberofelements
+	X=inv([md.x(md.elements(n,:)) md.y(md.elements(n,:)) ones(3,1)]);
+	alpha(n,:)=X(1,:);
+	beta(n,:)=X(2,:);
+	gamma(n,:)=X(3,:);
+end
+
+hu=md.thickness.*md.vx;
+hv=md.thickness.*md.vy;
+
+summation=[1;1;1];
+hux=(hu(md.elements).*alpha)*summation;
+hvy=(hv(md.elements).*beta)*summation;
+
+uelem=md.vx(md.elements)*summation/3;
+velem=md.vy(md.elements)*summation/3;
+
+dbdx=(md.bed(md.elements).*alpha)*summation;
+dbdy=(md.bed(md.elements).*beta)*summation;
+
+wb=-md.rho_ice/md.rho_water*(hux+hvy)+uelem.*dbdx+velem.*dbdy;
Index: /issm/trunk/src/m/model/collapse.m
===================================================================
--- /issm/trunk/src/m/model/collapse.m	(revision 5901)
+++ /issm/trunk/src/m/model/collapse.m	(revision 5901)
@@ -0,0 +1,120 @@
+function md=collapse(md)
+%COLLAPSE - collapses a 3d mesh into a 2d mesh
+%
+%   This routine collapses a 3d model into a 2d model
+%   and collapses all the fileds of the 3d model by
+%   taking their depth-averaged values
+%
+%   Usage:
+%      md=collapse(md)
+%
+%   See also: EXTRUDE, MODELEXTRACT
+
+%Check that the model is really a 3d model
+if ~md.dim==3,
+	error('collapse error message: only 3d mesh can be collapsed')
+end
+
+%Start with changing alle the fields from the 3d mesh 
+
+%drag is limited to grids that are on the bedrock.
+md.drag_coefficient=project2d(md,md.drag_coefficient,1);
+
+%p and q (same deal, except for element that are on the bedrock: )
+md.drag_p=project2d(md,md.drag_p,1);
+md.drag_q=project2d(md,md.drag_q,1);
+
+%observations
+md.vx_obs=project2d(md,md.vx_obs,md.numlayers);
+md.vy_obs=project2d(md,md.vy_obs,md.numlayers);
+md.vel_obs=project2d(md,md.vel_obs,md.numlayers);
+md.accumulation_rate=project2d(md,md.accumulation_rate,md.numlayers);
+md.firn_layer=project2d(md,md.firn_layer,md.numlayers);
+
+%results
+if ~isnan(md.vx),md.vx=DepthAverage(md,md.vx);end;
+if ~isnan(md.vy),md.vy=DepthAverage(md,md.vy);end;
+if ~isnan(md.vz),md.vz=DepthAverage(md,md.vz);end;
+if ~isnan(md.vel),md.vel=DepthAverage(md,md.vel);end;
+if ~isnan(md.surface_slopex),md.surface_slopex=project2d(md,md.surface_slopex,md.numlayers);end;
+if ~isnan(md.surface_slopey),md.surface_slopey=project2d(md,md.surface_slopey,md.numlayers);end;
+if ~isnan(md.bed_slopex),md.bed_slopex=project2d(md,md.bed_slopex,1);end;
+if ~isnan(md.bed_slopey),md.bed_slopey=project2d(md,md.bed_slopey,1);end;
+
+%bedinfo and surface info
+md.elementonbed=ones(md.numberofelements2d,1);
+md.elementonsurface=ones(md.numberofelements2d,1);
+md.gridonbed=ones(md.numberofgrids2d,1);
+md.gridonsurface=ones(md.numberofgrids2d,1);
+
+%elementstype
+if ~isnan(md.elements_type2d)
+	md.elements_type=md.elements_type2d; 
+elseif ~isnan(md.elements_type)
+	md.elements_type=project2d(md,md.elements_type,1);
+end	
+md.gridonhutter=project2d(md,md.gridonhutter,1);
+md.gridonmacayeal=project2d(md,md.gridonmacayeal,1);
+md.gridonpattyn=project2d(md,md.gridonpattyn,1);
+md.gridonstokes=project2d(md,md.gridonstokes,1);
+
+%boundary conditions
+md.spcvelocity=project2d(md,md.spcvelocity,md.numlayers);
+md.spcthickness=project2d(md,md.spcthickness,md.numlayers);
+md.spctemperature=project2d(md,md.spctemperature,md.numlayers);
+
+%Extrusion of Neumann BC
+%in 2d, segmentonnumann is: [grid1 grid2 element]
+numberofneumann2d=size(md.pressureload,1)/md.numlayers;
+md.pressureload=[md.pressureload(1:numberofneumann2d,1:2) md.pressureload(1:numberofneumann2d,5:6)]; %Add two columns on the first layer 
+
+%materials
+md.rheology_B=DepthAverage(md,md.rheology_B);
+md.rheology_n=project2d(md,md.rheology_n,1);
+
+%special for thermal modeling:
+md.melting_rate=project2d(md,md.melting_rate,1); 
+md.observed_temperature=DepthAverage(md,md.observed_temperature); 
+md.geothermalflux=project2d(md,md.geothermalflux,1); %bedrock only gets geothermal flux
+
+%update of connectivity matrix
+md.connectivity=25;
+
+%Collapse the mesh
+grids2d=md.numberofgrids2d;
+elements2d=md.numberofelements2d;
+
+%parameters
+md.surface=project2d(md,md.surface,1);
+md.thickness=project2d(md,md.thickness,1);
+md.bed=project2d(md,md.bed,1);
+md.gridonboundary=project2d(md,md.gridonboundary,1);
+md.elementoniceshelf=project2d(md,md.elementoniceshelf,1);
+md.gridoniceshelf=project2d(md,md.gridoniceshelf,1);
+md.elementonicesheet=project2d(md,md.elementonicesheet,1);
+md.gridonicesheet=project2d(md,md.gridonicesheet,1);
+
+%Initialize with the 2d mesh
+md.x=md.x2d;
+md.y=md.y2d;
+md.z=md.z2d;
+md.numberofgrids=md.numberofgrids2d;
+md.numberofelements=md.numberofelements2d;
+md.elements=md.elements2d;
+
+%Keep a trace of lower and upper grids
+md.lowergrids=NaN;
+md.uppergrids=NaN;
+
+%Remove old mesh 
+md.x2d=NaN;
+md.y2d=NaN;
+md.z2d=NaN;
+md.elements2d=NaN;
+md.elements_type2d=md.elements_type;
+md.numberofelements2d=md.numberofelements;
+md.numberofgrids2d=md.numberofgrids;
+md.numlayers=0;
+
+%Update mesh type
+md.dim=2;
Index: /issm/trunk/src/m/model/contourenvelope.m
===================================================================
--- /issm/trunk/src/m/model/contourenvelope.m	(revision 5901)
+++ /issm/trunk/src/m/model/contourenvelope.m	(revision 5901)
@@ -0,0 +1,97 @@
+function segments=contourenvelope(md,varargin)
+%CONTOURENVELOPE - build a set of segments enveloping a contour .exp
+%
+%   Usage:
+%      segments=contourenvelope(md,varargin)
+%
+%   Example:
+%      segments=contourenvelope(md,'Stream.exp');
+%      segments=contourenvelope(md);
+
+%some checks
+if nargin>2,
+	help contourenvelope
+	error('contourenvelope error message: bad usage');
+end
+if nargin==2,
+	file=varargin{1};
+	if ~exist(file),
+		error(['thicknessevolution error message: file ' file ' not found']);
+	end
+end
+
+%Now, build the connectivity tables for this mesh.
+%Computing connectivity
+if size(md.nodeconnectivity,1)~=md.numberofgrids,
+	md.nodeconnectivity=NodeConnectivity(md.elements,md.numberofgrids);
+end
+if size(md.elementconnectivity,1)~=md.numberofelements,
+	md.elementconnectivity=ElementConnectivity(md.elements,md.nodeconnectivity);
+end
+
+%get nodes inside profile
+elementconnectivity=md.elementconnectivity;
+if nargin==2,
+	%get flag list of elements and nodes inside the contour
+	nodein=ContourToMesh(md.elements,md.x,md.y,file,'node',1);
+	elemin=(sum(nodein(md.elements),2)==size(md.elements,2));
+	%modify element connectivity
+	elemout=find(~elemin);
+	elementconnectivity(elemout,:)=0;
+	elementconnectivity(find(ismember(elementconnectivity,elemout)))=0;
+end
+
+%Find element on boundary
+%First: find elements on the boundary of the domain
+flag=elementconnectivity;
+if nargin==2,
+	flag(find(flag))=elemin(flag(find(flag)));
+end
+elementonboundary=double(prod(flag,2)==0 & sum(flag,2)>0);
+
+%Find segments on boundary
+pos=find(elementonboundary);
+num_segments=length(pos);
+segments=zeros(num_segments,3);
+count=1;
+
+for i=1:num_segments,
+	el1=pos(i);
+	els2=elementconnectivity(el1,find(elementconnectivity(el1,:)));
+	if length(els2)>1,
+		flag=intersect(md.elements(els2(1),:),md.elements(els2(2),:));
+		nods1=md.elements(el1,:);
+		nods1(find(nods1==flag))=[];
+		segments(count,:)=[nods1 el1];
+
+		ord1=find(nods1(1)==md.elements(el1,:));
+		ord2=find(nods1(2)==md.elements(el1,:));
+
+		%swap segment grids if necessary
+		if ( (ord1==1 & ord2==2) | (ord1==2 & ord2==3) | (ord1==3 & ord2==1) ),
+			temp=segments(count,1);
+			segments(count,1)=segments(count,2);
+			segments(count,2)=temp;
+		end
+		segments(count,1:2)=fliplr(segments(count,1:2));
+		count=count+1;
+	else
+		nods1=md.elements(el1,:);
+		flag=setdiff(nods1,md.elements(els2,:));
+		for j=1:3,
+			nods=nods1; nods(j)=[];
+			if any(ismember(flag,nods)),
+				segments(count,:)=[nods el1];
+				ord1=find(nods(1)==md.elements(el1,:));
+				ord2=find(nods(2)==md.elements(el1,:));
+				if ( (ord1==1 & ord2==2) | (ord1==2 & ord2==3) | (ord1==3 & ord2==1) ),
+					temp=segments(count,1);
+					segments(count,1)=segments(count,2);
+					segments(count,2)=temp;
+				end
+				segments(count,1:2)=fliplr(segments(count,1:2));
+				count=count+1;
+			end
+		end
+	end
+end
Index: /issm/trunk/src/m/model/contourmassbalance.m
===================================================================
--- /issm/trunk/src/m/model/contourmassbalance.m	(revision 5901)
+++ /issm/trunk/src/m/model/contourmassbalance.m	(revision 5901)
@@ -0,0 +1,45 @@
+function dhdt=contourmassbalance(md,file)
+%CONTOURMASSBALANCE - compute the mass balance on a given profile
+%
+%   Usage:
+%      dhdt=contourmassbalance(md,file)
+
+%some checks
+if nargin~=2,
+	help contourmassbalance
+	error('contourmassbalance error message: bad usage');
+end
+if ((length(md.vx)~=md.numberofgrids)|(length(md.vy)~=md.numberofgrids))
+	error(['thicknessevolution error message: vx and vy should have a length of ' num2str(md.numberofgrids)])
+end
+if ~exist(file),
+	error(['thicknessevolution error message: file ' file ' not found']);
+end
+
+%Get segments enveloping contour
+segments=contourenvelope(md,file);
+%md.pressureload=segments; plotmodel(md,'data','pressureload','expdisp',file);
+
+%get flag list of elements and nodes inside the contour
+nodein=ContourToMesh(md.elements,md.x,md.y,file,'node',1);
+elemin=(sum(nodein(md.elements),2)==size(md.elements,2));
+
+%conputing Mass flux
+x=md.x;
+y=md.y;
+vx=mean(md.vx(segments(:,1:end-1)),2);
+vy=mean(md.vy(segments(:,1:end-1)),2);
+H=mean(md.thickness(segments(:,1:end-1)),2);
+nx=cos(atan2((x(segments(:,1))-x(segments(:,2))) , (y(segments(:,2))-y(segments(:,1)))));
+ny=sin(atan2((x(segments(:,1))-x(segments(:,2))) , (y(segments(:,2))-y(segments(:,1)))));
+L=sqrt((x(segments(:,1))-x(segments(:,2))).^2+(y(segments(:,2))-y(segments(:,1))).^2);
+flux = - md.rho_ice*sum(L.*H.*(vx.*nx+vy.*ny)); %outflux is negative!
+disp(['mass outflux on ' file ' = ' num2str(-flux/10^9) ' Gt/yr']);
+areas=GetAreas(md.elements,md.x,md.y);
+dhdt=flux/(sum(areas(find(elemin)))*md.rho_ice);
+disp(['dhdt on ' file ' (Flux  method) = ' num2str(dhdt) ' m/yr']);
+
+dhdt=thicknessevolution(md);
+in=find(elemin);
+dhdt=sum(dhdt(in).*areas(in))/sum(areas(in));
+disp(['dhdt on ' file ' (divHV method) = ' num2str(dhdt) ' m/yr']);
Index: /issm/trunk/src/m/model/deepcopy.m
===================================================================
--- /issm/trunk/src/m/model/deepcopy.m	(revision 5901)
+++ /issm/trunk/src/m/model/deepcopy.m	(revision 5901)
@@ -0,0 +1,30 @@
+function md2=deepcopy(md)
+%DEEPCOPY - copies a model
+%
+%   This routine will copy md into md2. If md is being held in an out of core 
+%   repository, user will be prompted for a different repository name, and a 
+%   copy of the repository, with the new name, will be done.
+%
+%   Usage:
+%      md2=deepcopy(md)
+
+if isempty(md.repository),
+	md2=md;
+else
+	%New repository name?
+	new_repository=input(['   input model is held in repository: ' md.repository '. you need a new name for the model copy: ']);
+	md2=model(new_repository);
+
+	structfields=fields(md);
+	for i=1:length(structfields),
+		field=structfields(i);field=field{1};
+		if strcmpi(field,'repository'),
+			%we don't want to clobber md2.repository!
+			continue;
+		end
+		fieldval=getfield(md,field);
+		if isfield(struct(md2),field),
+			eval(['md2.' field '=fieldval;']);
+		end
+	end
+end
Index: /issm/trunk/src/m/model/display/displaybc.m
===================================================================
--- /issm/trunk/src/m/model/display/displaybc.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displaybc.m	(revision 5901)
@@ -0,0 +1,29 @@
+function displaybc(md)
+%DISPLAYBC - display of the boundary conditions fileds
+%
+%   to avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays boundary conditions  from model md, 
+%   only if requested.
+%
+%   Usage:
+%      displaybc(md)
+
+disp(sprintf('   Boundary conditions:'));
+
+disp(sprintf('\n      geography:'));
+fielddisplay(md,'gridonboundary','grid on boundary flags list');
+fielddisplay(md,'elementoniceshelf','element on ice shelf flags list');
+fielddisplay(md,'gridoniceshelf','grid on ice shelf flags list');
+fielddisplay(md,'elementonicesheet','element on ice sheet flags list');
+fielddisplay(md,'gridonicesheet','grid on ice sheet flags list');
+
+disp(sprintf('\n      diagnostic:'));
+fielddisplay(md,'spcvelocity','constraints flag list (first 3 columns) and values [m/yr] (last 3 columns)');
+fielddisplay(md,'pressureload','segments on ice front list');
+
+disp(sprintf('\n      prognostic:'));
+fielddisplay(md,'spcthickness','constraints flag list (first column) and values (second column)');
+
+disp(sprintf('\n      thermal:'));
+fielddisplay(md,'spctemperature','constraints flag list (first column) and values (second column)');
+fielddisplay(md,'melting_rate','melting rate [m/a]');
Index: /issm/trunk/src/m/model/display/displaycontrol.m
===================================================================
--- /issm/trunk/src/m/model/display/displaycontrol.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displaycontrol.m	(revision 5901)
@@ -0,0 +1,31 @@
+function displaycontrol(md)
+%DISPLAYCONTROL - display control parameters
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays control parameters from model md, 
+%   only if requested.
+%
+%   Usage:
+%      displaycontrol(md)
+
+disp(sprintf('   Control solution parameters:\n'));
+if md.control_analysis,
+	fielddisplay(md,'control_type','parameter where inverse control is carried out; ex: DragCoefficientEnum, or RheologyBbarEnum)');
+	fielddisplay(md,'weights','weights applied to the misfit of each node');
+	fielddisplay(md,'nsteps','number of optimization searches');
+	fielddisplay(md,'eps_cm','misfit convergence criterion. Default is 1%, NaN if not applied');
+	fielddisplay(md,'optscal','scaling factor on gradient direction during optimization, for each optimization step');
+	fielddisplay(md,'cm_responses','indicate the type of response for each optimization steps: SurfaceAbsVelMisfitEnum, SurfaceRelVelMisfitEnum, SurfaceLogVelMisfitEnum, SurfaceLogVxVyMisfitEnum, SurfaceAverageVelMisfitEnum or ThicknessAbsMisfitEnum');
+	fielddisplay(md,'maxiter','maximum iterations during each optimization step');
+	fielddisplay(md,'tolx','minimum tolerance which will stop one optimization search');
+	fielddisplay(md,'cm_jump','decrease threshold for misfit, default is 30%');
+	fielddisplay(md,'cm_noisedmp','noise dampening coefficient, 0 if not applied');
+	fielddisplay(md,'cm_min','absolute minimum acceptable value of the inversed parameter');
+	fielddisplay(md,'cm_max','absolute maximum acceptable value of the inversed parameter');
+	fielddisplay(md,'cm_gradient','stop control method solution at gradient');
+	fielddisplay(md,'meanvel','velocity scaling factor when evaluating relative or logarithmic misfit');
+	fielddisplay(md,'epsvel','for relative fit, avoids misfit becoming infinity, for logarithmic fit, threshold for velocity');
+	fielddisplay(md,'plot','visualization of the results of each iteration yes -> 1 no -> 0. Default is 1');
+else
+	disp(sprintf('         %s','no scheduled control. activate by doing md.control_analysis=1'));
+end
Index: /issm/trunk/src/m/model/display/displaydiagnostic.m
===================================================================
--- /issm/trunk/src/m/model/display/displaydiagnostic.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displaydiagnostic.m	(revision 5901)
@@ -0,0 +1,36 @@
+function displaydiagnostic(md)
+%DISPLAYDIAGNOSTIC - display solution parameters of diagnostic
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays the solution parameters
+%   from model md, only if requested.
+%
+%   Usage:
+%      displaydiagnostic(md)
+
+disp(sprintf('   Diagnostic solution parameters:'));
+
+disp(sprintf('\n      %s','Newton convergence criteria:'));
+fielddisplay(md,'eps_res','mechanical equilibrium residue convergence criterion');
+fielddisplay(md,'eps_rel','velocity relative convergence criterion, NaN -> not applied');
+fielddisplay(md,'eps_abs','velocity absolute convergence criterion, NaN -> not applied');
+fielddisplay(md,'max_nonlinear_iterations','maximum number of nonlinear iterations');
+fielddisplay(md,'viscosity_overshoot','over-shooting constant new=new+C*(new-old)');
+
+disp(sprintf('\n      boundary conditions:'));
+fielddisplay(md,'spcvelocity','constraints flag list (first 3 columns) and values [m/yr] (last 3 columns)');
+fielddisplay(md,'pressureload','segments on ice front list');
+
+disp(sprintf('\n      %s','Penalties:'));
+fielddisplay(md,'penalty_offset','offset used by penalties: penalty = Kmax*10^offset');
+fielddisplay(md,'min_mechanical_constraints','threshold for instability of mechanical constraints');
+
+disp(sprintf('\n      %s','Memory management:'));
+fielddisplay(md,'lowmem','Set to 1 if you are running low on cluster memory');
+fielddisplay(md,'sparsity','matrix sparsity. Set to .001 for < 1M dof, .0001 for 5M dof, and .00001 for > 10M dof');
+fielddisplay(md,'connectivity','element connectivity');
+
+disp(sprintf('\n      %s','Debugging:'));
+fielddisplay(md,'verbose','level of output statements: none -> 0, yes->1,2. Default is 0');
+fielddisplay(md,'element_debug','output debug statements for elementswhen possible yes-> 1, no -> 0. Default is 0');
+fielddisplay(md,'element_debugid','if element_debug on, id of element for which to output messages');
Index: /issm/trunk/src/m/model/display/displayexppar.m
===================================================================
--- /issm/trunk/src/m/model/display/displayexppar.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displayexppar.m	(revision 5901)
@@ -0,0 +1,18 @@
+function displayoutlines(md);
+%DISPLAYOUTLINES - display outline information
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays outline information from model md, 
+%   only if requested.
+%
+%   Usage:
+%      displayoutline(md)
+
+disp(sprintf('\n   Outlines:'));
+fielddisplay(md,'domainoutline','domain outline Argus file');
+fielddisplay(md,'riftoutline','rift outline Argus file');
+fielddisplay(md,'iceshelfoutline','ice shelf outline Argus file');
+fielddisplay(md,'icesheetoutline','ice sheet outline Argus file');
+
+disp(sprintf('\n   Model files:'));
+fielddisplay(md,'parameterfile','parameter file content');
Index: /issm/trunk/src/m/model/display/displaymaterials.m
===================================================================
--- /issm/trunk/src/m/model/display/displaymaterials.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displaymaterials.m	(revision 5901)
@@ -0,0 +1,23 @@
+function displaymaterials(md)
+%DISPLAYCONTROL - display material parameters
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays material parameters from model md, 
+%   only if requested.
+%
+%   Usage:
+%      displaymaterials(md)
+
+disp(sprintf('   Materials:\n'));
+
+fielddisplay(md,'rho_ice','ice density [kg/m^3]');
+fielddisplay(md,'rho_water','water density [kg/m^3]');
+fielddisplay(md,'rheology_B','flow law parameter [Pa/s^(1/n)]');
+fielddisplay(md,'rheology_n','Glen''s flow law exponent');
+fielddisplay(md,'heatcapacity','heat capacity [J/kg/K]');
+fielddisplay(md,'thermalconductivity','ice thermal conductivity [W/m/K]');
+fielddisplay(md,'meltingpoint','melting point of ice at 1atm in K');
+fielddisplay(md,'latentheat','latent heat of fusion [J/m^3]');
+fielddisplay(md,'beta','rate of change of melting point with pressure [K/Pa]');
+fielddisplay(md,'mixed_layer_capacity','mixed layer capacity [W/kg/K]');
+fielddisplay(md,'thermal_exchange_velocity','thermal exchange velocity [m/s]');
Index: /issm/trunk/src/m/model/display/displaymesh.m
===================================================================
--- /issm/trunk/src/m/model/display/displaymesh.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displaymesh.m	(revision 5901)
@@ -0,0 +1,46 @@
+function displaymesh(md)
+%DISPLAYMESH - display mesh information
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays mesh information from model md, 
+%   only if requested.
+%
+%   Usage:
+%      displaymesh(md)
+
+disp(sprintf('   Mesh:')); 
+
+if md.dim==3,
+
+	disp(sprintf('\n      Elements and nodes of the original 2d mesh:'));
+	fielddisplay(md,'numberofelements2d','number of elements');
+	fielddisplay(md,'numberofgrids2d','number of nodes');
+	fielddisplay(md,'elements2d','index into (x,y,z), coordinates of the grids');
+	fielddisplay(md,'elements_type2d','element types');
+	fielddisplay(md,'x2d','nodes x coordinate');
+	fielddisplay(md,'y2d','nodes y coordinate');
+	fielddisplay(md,'z2d','nodes z coordinate');
+
+	disp(sprintf('\n      Elements and nodes of the extruded 3d mesh:'));
+else
+	disp(sprintf('\n      Elements and nodes:'));
+end
+fielddisplay(md,'numberofelements','number of elements');
+fielddisplay(md,'numberofgrids','number of nodes');
+fielddisplay(md,'elements','index into (x,y,z), coordinates of the grids');
+fielddisplay(md,'elements_type','element types');
+fielddisplay(md,'x','nodes x coordinate');
+fielddisplay(md,'y','nodes y coordinate');
+fielddisplay(md,'z','nodes z coordinate');
+fielddisplay(md,'edges','edges of the 2d mesh (node1 node2 element1 element2)');
+
+disp(sprintf('\n      Properties:'));
+fielddisplay(md,'dim','mesh dimension (2d or 3d)');
+fielddisplay(md,'numlayers','number of extrusion layers');
+fielddisplay(md,'extrusionexponent','exponent for extrusion');
+fielddisplay(md,'bamg','Geometry and 2d mesh properties (if generated by Bamg)');
+fielddisplay(md,'penalties','penalties list');
+fielddisplay(md,'gridonbed','lower nodes flags list');
+fielddisplay(md,'elementonbed','lower elements flags list');
+fielddisplay(md,'gridonsurface','upper nodes flags list');
+fielddisplay(md,'elementonsurface','upper elements flags list');
Index: /issm/trunk/src/m/model/display/displayobservations.m
===================================================================
--- /issm/trunk/src/m/model/display/displayobservations.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displayobservations.m	(revision 5901)
@@ -0,0 +1,22 @@
+function displayobservations(md)
+%DISPLAYOBSERVATIONS - display observations information
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays observations information from model md, 
+%   only if requested.
+%
+%   Usage:
+%      displayobservations(md)
+
+disp(sprintf('   Observations:\n'));
+
+fielddisplay(md,'vx_obs','observed velocity x component [m/a]');
+fielddisplay(md,'vy_obs','observed velocity y component [m/a]');
+fielddisplay(md,'vel_obs','observed velocity magnitude [m/a]');
+fielddisplay(md,'vx_obs_raw','raw observedvelocity x component [m/a]');
+fielddisplay(md,'vy_obs_raw','raw observed velocity y component [m/a]');
+fielddisplay(md,'vel_obs_raw','raw observed magnitude [m/a]');
+fielddisplay(md,'accumulation_rate','surface accumulation rate [m/a]');
+fielddisplay(md,'dhdt','surface dhdt rate [m/a]');
+fielddisplay(md,'observed_temperature','observed temperature [K]');
+fielddisplay(md,'geothermalflux','geothermal heat flux [W/m^2]');
Index: /issm/trunk/src/m/model/display/displayparallel.m
===================================================================
--- /issm/trunk/src/m/model/display/displayparallel.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displayparallel.m	(revision 5901)
@@ -0,0 +1,23 @@
+function displayparallel(md)
+%DISPLAYPARALLEL - display parallel computation parameters
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays all fields related to
+%   parallel computation from model md, only if requested.
+%
+%   Usage:
+%      displayparallel(md)
+
+disp(sprintf('   parallel computation parameters:'));
+
+disp(sprintf('\n      parallelisation:'));
+fielddisplay(md,'cluster','set to ''cluster_name'' to run in cluster, ''none'' to run serially');
+fielddisplay(md,'np','number of CPUS requested on cluster');
+fielddisplay(md,'exclusive','set to 1 if CPUS used are not to be shared with other users, 0 otherwise');
+fielddisplay(md,'time','amount of time requested on cluster');
+fielddisplay(md,'alloc_cleanup','allocation cleanup before starting a job, default 1');
+fielddisplay(md,'waitonlock','maximum number of minutes to wait for batch results, or return 0');
+fielddisplay(md,'queue','special queue name on cluster? default is '''' ');
+
+disp(sprintf('\n      PETSc solver options:'));
+fielddisplay(md,'solverstring','solver string for Petsc. See solversetto... routines. Default is mumps');
Index: /issm/trunk/src/m/model/display/displayparameters.m
===================================================================
--- /issm/trunk/src/m/model/display/displayparameters.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displayparameters.m	(revision 5901)
@@ -0,0 +1,31 @@
+function displayparameters(md)
+%DISPLAYPARAMETERS - display parameters
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays parameters from model md, 
+%   only if requested.
+%
+%   Usage:
+%      displayparameters(md)
+
+disp(sprintf('   Parameters:'));
+
+disp(sprintf('\n      geometrical parameters:'));
+fielddisplay(md,'surface','surface height [m]');
+fielddisplay(md,'thickness','thickness [m]');
+fielddisplay(md,'bed','bed height [m]');
+fielddisplay(md,'bathymetry','bathymetry elevation (with respect to sea level) [m]');
+fielddisplay(md,'firn_layer','firn layer height [m]');
+fielddisplay(md,'elementonbed','element on bed flags list');
+fielddisplay(md,'elementonsurface','element on surface flags list');
+fielddisplay(md,'gridonbed','grid on bed flags list');
+fielddisplay(md,'gridonsurface','grid on surface flags list');
+
+disp(sprintf('\n      physical parameters:'));
+fielddisplay(md,'g','acceleration due to gravity [m/s^2]');
+
+disp(sprintf('\n      Friction parameters (Sigma= drag^2 * Neff ^r * u ^s, with Neff=rho_ice*g*thickness+rho_ice*g*bed, r=q/p and s=1/p)'));
+fielddisplay(md,'drag_type','0: none, 1:plastic, 2:viscous');
+fielddisplay(md,'drag_coefficient','friction coefficient [IS]');
+fielddisplay(md,'drag_p','p exponent');
+fielddisplay(md,'drag_q','q exponent');
Index: /issm/trunk/src/m/model/display/displayprognostic.m
===================================================================
--- /issm/trunk/src/m/model/display/displayprognostic.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displayprognostic.m	(revision 5901)
@@ -0,0 +1,20 @@
+function displayprognostic(md)
+%DISPLAYPROGNOSTIC - display solution parameters
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays the solution parameters
+%   from model md, only if requested.
+%
+%   Usage:
+%      displayprognostic(md)
+
+disp(sprintf('   Prognostic solution parameters:'));
+
+disp(sprintf('\n      transient:'));
+fielddisplay(md,'dt','time step [yr]');
+fielddisplay(md,'ndt','time span [yr]');
+fielddisplay(md,'artificial_diffusivity','yes->1, no->0');
+fielddisplay(md,'prognostic_DG','yes->1, no->0');
+
+disp(sprintf('\n      boundary conditions:'));
+fielddisplay(md,'spcthickness','constraints flag list (first column) and values (second column)');
Index: /issm/trunk/src/m/model/display/displayqmu.m
===================================================================
--- /issm/trunk/src/m/model/display/displayqmu.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displayqmu.m	(revision 5901)
@@ -0,0 +1,93 @@
+function displayqmu(md)
+%DISPLAYQMU - display qmu computation parameters
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays all fields related to
+%   qmu computation from model md, only if requested.
+%
+%   Usage:
+%      displayqmu(md)
+
+disp(sprintf('      ''%s''','qmu using Dakota'));
+
+if ~md.qmu_analysis,
+	disp(sprintf('         %s','no scheduled qmu. activate by doing md.qmu_analysis=1'));
+else
+
+	for i=1:numel(md.variables)
+		disp(sprintf('         variables%s:  (arrays of each variable class)',...
+			string_dim(md.variables,i)));
+		fnames=fieldnames(md.variables(i));
+		maxlen=0;
+		for j=1:numel(fnames)
+			maxlen=max(maxlen,length(fnames{j}));
+		end
+		
+		for j=1:numel(fnames)
+			disp(sprintf(['            %-' num2str(maxlen+1) 's:    [%ix%i]    ''%s'''],...
+				fnames{j},size(md.variables.(fnames{j})),class(md.variables.(fnames{j}))));
+		end
+	end
+
+
+	for i=1:numel(md.responses)
+		disp(sprintf('         responses%s:  (arrays of each response class)',...
+			string_dim(md.responses,i)));
+		fnames=fieldnames(md.responses(i));
+		maxlen=0;
+		for j=1:numel(fnames)
+			maxlen=max(maxlen,length(fnames{j}));
+		end
+		
+		for j=1:numel(fnames)
+			disp(sprintf(['            %-' num2str(maxlen+1) 's:    [%ix%i]    ''%s'''],...
+				fnames{j},size(md.responses.(fnames{j})),class(md.responses.(fnames{j}))));
+		end
+	end
+
+
+	disp(sprintf('         qmu_method:  (array of dakota_method class)'));
+	for i=1:numel(md.qmu_method);
+		if strcmp(class(md.qmu_method(i)),'dakota_method')
+			disp(sprintf('            method%s :    ''%s''',...
+				string_dim(md.qmu_method,i),md.qmu_method(i).method));
+		end
+	end
+
+	for i=1:numel(md.qmu_params)
+		disp(sprintf('         qmu_params%s:  (array of method-independent parameters)',...
+			string_dim(md.qmu_params,i)));
+		fnames=fieldnames(md.qmu_params(i));
+		maxlen=0;
+		for j=1:numel(fnames)
+			maxlen=max(maxlen,length(fnames{j}));
+		end
+		
+		for j=1:numel(fnames)
+			disp(sprintf(['            %-' num2str(maxlen+1) 's: %s'],...
+				fnames{j},any2str(md.qmu_params(i).(fnames{j}))));
+		end
+	end
+
+	for i=1:numel(md.dakotaresults)
+		disp(sprintf('         dakotaresults%s:  (information from dakota files)',...
+			string_dim(md.dakotaresults,i)));
+		fnames=fieldnames(md.dakotaresults(i));
+		maxlen=0;
+		for j=1:numel(fnames)
+			maxlen=max(maxlen,length(fnames{j}));
+		end
+		
+		for j=1:numel(fnames)
+			disp(sprintf(['            %-' num2str(maxlen+1) 's:    [%ix%i]    ''%s'''],...
+				fnames{j},size(md.dakotaresults.(fnames{j})),class(md.dakotaresults.(fnames{j}))));
+		end
+	end
+
+	if isempty(md.dakotain), disp(sprintf('         dakotain: N/A')); else disp(sprintf('         dakotain:    [%ix%i]    (can be accessed by typing md.dakotain)',size(md.dakotain)));end
+	if isempty(md.dakotaout), disp(sprintf('         dakotaout: N/A')); else disp(sprintf('         dakotaout:    [%ix%i]    (can be accessed by typing md.dakotaout)',size(md.dakotaout)));end
+	if isempty(md.dakotadat), disp(sprintf('         dakotadat: N/A')); else disp(sprintf('         dakotadat:    [%ix%i]    (can be accessed by typing md.dakotadat)',size(md.dakotadat)));end
+	disp(sprintf('         npart   : %i (number of partitions for semi-descrete qmu)',md.npart));
+	disp(sprintf('         part    : [%i] (user provided mesh partition, defaults to metis if not specified)',length(md.part)));
+
+end
Index: /issm/trunk/src/m/model/display/displayresults.m
===================================================================
--- /issm/trunk/src/m/model/display/displayresults.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displayresults.m	(revision 5901)
@@ -0,0 +1,19 @@
+function displayresults(md)
+%DISPLAYRESULTS - display results
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays results from model md, 
+%   only if requested.
+%
+%   Usage:
+%      displayresults(md)
+
+disp(sprintf('   Results:'));
+
+disp(sprintf('\n      solution results:'));
+fielddisplay(md,'results','');
+
+disp(sprintf('\n      output parameters:'));
+fielddisplay(md,'stress','stress [Pa]');
+fielddisplay(md,'deviatoricstress','deviatoric stress [Pa]');
+fielddisplay(md,'strainrate','strain rate [1/yr]');
Index: /issm/trunk/src/m/model/display/displaythermal.m
===================================================================
--- /issm/trunk/src/m/model/display/displaythermal.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displaythermal.m	(revision 5901)
@@ -0,0 +1,23 @@
+function displaythermal(md)
+%DISPLAYTHERMAL - display solution parameters applied to thermal model
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays the solution parameters
+%   from model md, only if requested.
+%
+%   Usage:
+%      displaythermal(md)
+
+disp(sprintf('   Thermal solution parameters:'));
+
+disp(sprintf('\n      parameters:'));
+fielddisplay(md,'stabilize_constraints','stabilize unstable thermal constraints that keep zigzagging after n iteration (default is 0, no stabilization)');
+fielddisplay(md,'min_thermal_constraints','threshold to declare convergence of thermal solution (default is 0)');
+
+disp(sprintf('\n      boundary conditions:'));
+fielddisplay(md,'spctemperature','constraints flag list (first column) and values (second column)');
+fielddisplay(md,'melting_rate','melting rate [m/a]');
+
+disp(sprintf('\n      transient:'));
+fielddisplay(md,'dt','time step [yr]');
+fielddisplay(md,'ndt','time span [yr]');
Index: /issm/trunk/src/m/model/display/displaytransient.m
===================================================================
--- /issm/trunk/src/m/model/display/displaytransient.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/displaytransient.m	(revision 5901)
@@ -0,0 +1,28 @@
+function displaytransient(md)
+%DISPLAYTRANSIENT - display solution parameters
+%
+%   To avoid clobbering display.m with every field from model md, 
+%   we create this routine that displays the solution parameters
+%   from model md, only if requested.
+%
+%   Usage:
+%      displaytransient(md)
+
+disp('Transient parameters on a pure solution basis:');
+disp(' ');
+displaydiagnostic(md);
+disp(' ');
+displaythermal(md);
+disp(' ');
+displayprognostic(md);
+disp(' ');
+
+disp(sprintf('   Transient solution parameters:\n'));
+
+fielddisplay(md,'timestepping','adptative time stepping implemented - default to 0');
+fielddisplay(md,'deltaH','minimum thickness difference between two time steps');
+fielddisplay(md,'DeltaH','maximum thickness difference between two time steps');
+fielddisplay(md,'deltaT','minimum temperature difference between two time steps');
+fielddisplay(md,'DeltaT','maximum temperature difference between two time steps');
+fielddisplay(md,'timeacc','multiplier to time step when time stepping increases time step');
+fielddisplay(md,'timedec','multiplier to time step when time stepping decresaes time step');
Index: /issm/trunk/src/m/model/display/fielddisplay.m
===================================================================
--- /issm/trunk/src/m/model/display/fielddisplay.m	(revision 5901)
+++ /issm/trunk/src/m/model/display/fielddisplay.m	(revision 5901)
@@ -0,0 +1,124 @@
+function fielddisplay(md,name,comment)
+%FIELDDISPLAY - display model field
+%
+%   Usage:
+%      fielddisplay(md,offset,name,comment)
+
+	%get field
+	field=md.(name);
+
+	%disp corresponding line as a function of field type (offset set as 9 spaces)
+	parsedisplay('         ',name,field,comment);
+
+end %function
+
+function parsedisplay(offset,name,field,comment);
+
+	%string
+	if ischar(field),
+
+		if length(field)>30;
+			displayunit(offset,name,'not displayed',comment),
+		else
+			displayunit(offset,name,['''' field ''''],comment),
+		end
+
+	%numeric
+	elseif isnumeric(field)
+
+		%get size
+		fieldsize=size(field);
+
+		%double
+		if max(fieldsize)==1,
+			displayunit(offset,name,num2str(field),comment),
+		%matrix
+		else
+			displayunit(offset,name,['(' num2str(fieldsize(1)) 'x' num2str(fieldsize(2)) ')'],comment),
+		end
+
+		%structure
+	elseif isstruct(field),
+		struct_display(field,offset),
+
+	%cell
+	elseif iscell(field),
+		cell_display(offset,name,field,comment),
+
+	else
+		displayunit(offset,name,'not displayed',comment),
+
+	end
+end %function
+
+function struct_display(structure,offset)
+
+	structure_fields=fields(structure);
+
+	for i=1:length(structure_fields),
+
+		%get current field
+		field=structure.(structure_fields{i});
+
+		%recursive call if necessary
+		if isstruct(field),
+			disp(sprintf('%s',[offset structure_fields{i} ':']));
+			struct_display(field,[offset '   ']);
+
+		%display value
+		else
+			parsedisplay(offset,structure_fields{i},field,'');
+		end
+	end
+end
+
+function cell_display(offset,name,field,comment)
+
+	%initialization
+	string='{';
+
+	%go through the cell and fill string
+	if length(field)<5;
+		for i=1:length(field),
+			if ischar(field{i}),
+				string=[string ''''  field{i} ''','];
+			elseif (isnumeric(field{i}) & length(field{i})==1)
+				string=[string num2str(field{i}) ',' ];
+			else
+				string='{';
+				break
+			end
+		end
+	end
+	if strcmp(string,'{'),
+		string=['(' num2str(size(field,1)) 'x' num2str(size(field,2)) ')'];
+	else
+		string=[string(1:end-1) '}'];
+	end
+
+	%call displayunit
+	displayunit(offset,name,string,comment);
+end
+
+function displayunit(offset,name,caracterization,comment),
+
+	%take care of name
+	if length(name)>23,
+		name=[name(1:20) '...'];
+	end
+
+	%take care of caracterization
+	if (strcmp(caracterization,['''' '''']) | strcmp(caracterization,'NaN')),
+		caracterization='N/A';
+	end
+	if length(caracterization)>15,
+		caracterization=[caracterization(1:12) '...'];
+	end
+
+	%print
+	if isempty(comment)
+		disp(sprintf('%s%-23s: %-15s',offset,name,caracterization));
+	else
+		disp(sprintf('%s%-23s: %-15s -- %s',offset,name,caracterization,comment));
+	end
+end
Index: /issm/trunk/src/m/model/drivingstress.m
===================================================================
--- /issm/trunk/src/m/model/drivingstress.m	(revision 5901)
+++ /issm/trunk/src/m/model/drivingstress.m	(revision 5901)
@@ -0,0 +1,18 @@
+function [px,py,pmag]=drivingstress(md)
+%DRIVINGSTRESS -  evaluates the driving stress
+%
+%   The driving stress is computed according to the following formula: 
+%   driving stress= rho_ice*g*H*slope
+%
+%   Usage:
+%      [Fx,Fy,Fmag]=drivingstress(md)
+
+%Get slope
+[sx,sy,s]=slope(md);
+
+%Average thickness over elements
+thickness_bar=(md.thickness(md.elements(:,1))+md.thickness(md.elements(:,2))+md.thickness(md.elements(:,3)))/3;
+
+px=md.rho_ice*md.g*thickness_bar.*sx;
+py=md.rho_ice*md.g*thickness_bar.*sy;
+pmag=sqrt(px.^2+py.^2);
Index: /issm/trunk/src/m/model/effectivepressure.m
===================================================================
--- /issm/trunk/src/m/model/effectivepressure.m	(revision 5901)
+++ /issm/trunk/src/m/model/effectivepressure.m	(revision 5901)
@@ -0,0 +1,16 @@
+function Neff=effectivepressure(md)
+%EFFECTIVEPRESSURE - compute effective pressure
+%
+%   Usage:
+%      Neff=effectivepressure(md)
+%
+%   Example:
+%      Neff=effectivepressure(md)
+%
+
+
+Neff=md.rho_ice*md.g*md.thickness+md.rho_ice*md.g*md.bed;
+
+
+pos=find(Neff<0);
+Neff(pos)=0;
Index: /issm/trunk/src/m/model/export.m
===================================================================
--- /issm/trunk/src/m/model/export.m	(revision 5901)
+++ /issm/trunk/src/m/model/export.m	(revision 5901)
@@ -0,0 +1,16 @@
+function export_results=export(md,results, xlower,ylower,xposting,yposting,xsize,ysize)
+%EXPORT - exports results from a mesh to a regular grid
+%
+%   this routine exports results from a mesh to a regular grid 
+%   of postings (xposting,yposint) with coordinates for lower left 
+%   corner (xlower,ylower), and of size (xsize,ysize) 
+%
+%   Usage:
+%      export_results=export(md,results, xlower,ylower,xposting,yposting,xsize,ysize)
+
+%Build x_m and y_m
+x_m=(xlower):xposting:(xlower+xposting*(xsize-1));
+y_m=(ylower):yposting:(ylower+yposting*(ysize-1));
+
+[X,Y]=meshgrid(x_m,y_m);
+export_results=griddata(md.x,md.y,results,X,Y);
Index: /issm/trunk/src/m/model/extrude.m
===================================================================
--- /issm/trunk/src/m/model/extrude.m	(revision 5901)
+++ /issm/trunk/src/m/model/extrude.m	(revision 5901)
@@ -0,0 +1,242 @@
+function md=extrude(md,varargin)
+%EXTRUDE - vertically extrude a 2d mesh
+%
+%   vertically extrude a 2d mesh and create corresponding 3d mesh.
+%   The vertical distribution can:
+%    - follow a polynomial law
+%    - follow two polynomial laws, one for the lower part and one for the upper part of the mesh
+%    - be discribed by a list of coefficients (between 0 and 1)
+%   
+%
+%   Usage:
+%      md=extrude(md,numlayers,extrusionexponent);
+%      md=extrude(md,numlayers,lowerexponent,upperexponent);
+%      md=extrude(md,listofcoefficients);
+%
+%   Example:
+%      md=extrude(md,8,3);
+%      md=extrude(md,8,3,2);
+%      md=extrude(md,[0 0.2 0.5 0.7 0.9 0.95 1]);
+%
+%   See also: MODELEXTRACT, COLLAPSE
+
+%some checks on list of arguments
+if ((nargin>4) | (nargin<2) | (nargout~=1)),
+	help extrude;
+	error('extrude error message');
+end
+
+if md.counter<3,
+	help extrude;
+	error('only fully parameterized 2d models can be extruded');
+end
+
+if md.counter>=4,
+	error('This model has already been extruded!','s');
+end
+
+%Extrude the mesh
+if nargin==2, %list of coefficients
+	list=varargin{1};
+	if any(list<0) | any(list>1),
+		error('extrusioncoefficients must be between 0 and 1');
+	end
+	extrusionlist=sort(unique([list(:);0;1]));
+	numlayers=length(extrusionlist);
+elseif nargin==3, %one polynomial law
+	if varargin{2}<=0,
+		help extrude;
+		error('extrusionexponent must be >=0');
+	end
+	numlayers=varargin{1};
+	extrusionlist=((0:1:numlayers-1)/(numlayers-1)).^varargin{2};
+elseif nargin==4, %two polynomial laws
+	numlayers=varargin{1};
+	lowerexp=varargin{2};
+	upperexp=varargin{3};
+
+	if varargin{2}<=0 | varargin{3}<=0,
+		help extrude;
+		error('lower and upper extrusionexponents must be >=0');
+	end
+
+	lowerextrusionlist=[(0:2/(numlayers-1):1).^lowerexp]/2;
+	upperextrusionlist=[(0:2/(numlayers-1):1).^upperexp]/2;
+	extrusionlist=sort(unique([lowerextrusionlist 1-upperextrusionlist]));
+
+end
+
+if numlayers<2,
+	disp('number of layers should be at least 2. returning initial model...');
+	return
+end
+
+%Initialize with the 2d mesh
+x3d=[]; 
+y3d=[];
+z3d=[];  %the lower grid is on the bed
+thickness3d=md.thickness; %thickness and bed for these grids
+bed3d=md.bed;
+
+%Create the new layers
+for i=1:numlayers,
+	x3d=[x3d; md.x]; 
+	y3d=[y3d; md.y];
+	%grids are distributed between bed and surface accordingly to the given exponent
+	z3d=[z3d; bed3d+thickness3d*extrusionlist(i)]; 
+end
+number_grids3d=size(x3d,1); %number of 3d grids for the non extruded part of the mesh
+
+%Extrude elements 
+elements3d=[];
+for i=1:numlayers-1,
+	elements3d=[elements3d;[md.elements+(i-1)*md.numberofgrids md.elements+i*md.numberofgrids]]; %Create the elements of the 3d mesh for the non extruded part
+end
+number_el3d=size(elements3d,1); %number of 3d grids for the non extruded part of the mesh
+
+%Keep a trace of lower and upper grids
+lowergrids=NaN*ones(number_grids3d,1);
+uppergrids=NaN*ones(number_grids3d,1);
+lowergrids(md.numberofgrids+1:end)=1:(numlayers-1)*md.numberofgrids;
+uppergrids(1:(numlayers-1)*md.numberofgrids)=md.numberofgrids+1:number_grids3d;
+md.lowergrids=lowergrids;
+md.uppergrids=uppergrids;
+
+%same for lower and upper elements
+lowerelements=NaN*ones(number_el3d,1);
+upperelements=NaN*ones(number_el3d,1);
+lowerelements(md.numberofelements+1:end)=1:(numlayers-2)*md.numberofelements;
+upperelements(1:(numlayers-2)*md.numberofelements)=md.numberofelements+1:(numlayers-1)*md.numberofelements;
+md.lowerelements=lowerelements;
+md.upperelements=upperelements;
+
+
+
+%Save old mesh 
+md.x2d=md.x;
+md.y2d=md.y;
+md.z2d=md.z;
+md.elements2d=md.elements;
+md.elements_type2d=md.elements_type;
+md.vertices_type2d=md.vertices_type;
+md.numberofelements2d=md.numberofelements;
+md.numberofgrids2d=md.numberofgrids;
+
+%Update mesh type
+md.dim=3;
+
+%Build global 3d mesh 
+md.elements=elements3d;
+md.x=x3d;
+md.y=y3d;
+md.z=z3d;
+md.numberofelements=number_el3d;
+md.numberofgrids=number_grids3d;
+md.numlayers=numlayers;
+
+%Ok, now deal with the other fields from the 2d mesh:
+
+%drag_coefficient is limited to grids that are on the bedrock.
+md.drag_coefficient=project3d(md,md.drag_coefficient,'node',1);
+
+%p and q (same deal, except for element that are on the bedrock: )
+md.drag_p=project3d(md,md.drag_p,'element');
+md.drag_q=project3d(md,md.drag_q,'element');
+
+%observations
+md.vx_obs=project3d(md,md.vx_obs,'node');
+md.vy_obs=project3d(md,md.vy_obs,'node');
+md.vel_obs=project3d(md,md.vel_obs,'node');
+md.vx_bal=project3d(md,md.vx_bal,'node');
+md.vy_bal=project3d(md,md.vy_bal,'node');
+md.vel_bal=project3d(md,md.vel_bal,'node');
+md.vel_obs_raw=project3d(md,md.vel_obs_raw,'node');
+md.accumulation_rate=project3d(md,md.accumulation_rate,'node');
+md.dhdt=project3d(md,md.dhdt,'node');
+md.firn_layer=project3d(md,md.firn_layer,'node',md.numlayers);
+
+%results
+if ~isnan(md.vx),md.vx=project3d(md,md.vx,'node');end;
+if ~isnan(md.vy),md.vy=project3d(md,md.vy,'node');end;
+if ~isnan(md.vz),md.vz=project3d(md,md.vz,'node');end;
+if ~isnan(md.vel),md.vel=project3d(md,md.vel,'node');end;
+if ~isnan(md.temperature),md.temperature=project3d(md,md.temperature,'node');end;
+if ~isnan(md.surface_slopex),md.surface_slopex=project3d(md,md.surface_slopex,'node');end;
+if ~isnan(md.surface_slopey),md.surface_slopey=project3d(md,md.surface_slopey,'node');end;
+if ~isnan(md.bed_slopex),md.bed_slopex=project3d(md,md.bed_slopex,'node');end;
+if ~isnan(md.bed_slopey),md.bed_slopey=project3d(md,md.bed_slopey,'node');end;
+
+%bedinfo and surface info
+md.elementonbed=project3d(md,ones(md.numberofelements2d,1),'element',1);
+md.elementonsurface=project3d(md,ones(md.numberofelements2d,1),'element',md.numlayers-1);
+md.gridonbed=project3d(md,ones(md.numberofgrids2d,1),'node',1);
+md.gridonsurface=project3d(md,ones(md.numberofgrids2d,1),'node',md.numlayers);
+
+%elementstype
+if ~isnan(md.elements_type)
+	oldelements_type=md.elements_type2d;
+	md.elements_type=zeros(number_el3d,1);
+	md.elements_type=project3d(md,oldelements_type,'element');
+	md.gridonhutter=project3d(md,md.gridonhutter,'node');
+	md.gridonmacayeal=project3d(md,md.gridonmacayeal,'node');
+	md.gridonpattyn=project3d(md,md.gridonpattyn,'node');
+	md.gridonstokes=project3d(md,md.gridonstokes,'node');
+end
+
+%verticestype
+if ~isnan(md.vertices_type)
+	oldvertices_type=md.vertices_type2d;
+	md.vertices_type=zeros(number_grids3d,1);
+	md.vertices_type=project3d(md,oldvertices_type,'node');
+end
+
+%boundary conditions
+md.spcvelocity=project3d(md,md.spcvelocity,'node');
+md.spctemperature=project3d(md,md.spctemperature,'node',md.numlayers);
+md.spcthickness=project3d(md,md.spcthickness,'node');
+
+%Extrusion of Neumann BC
+%in 3d, segmentonnumann is: [grid1 grid2 grid3 grid4 element]
+pressureload_layer1=[md.pressureload(:,1:2)  md.pressureload(:,2)+md.numberofgrids2d  md.pressureload(:,1)+md.numberofgrids2d  md.pressureload(:,3:4)]; %Add two columns on the first layer 
+pressureload=[];
+for i=1:numlayers-1,
+	pressureload=[pressureload ;pressureload_layer1(:,1:4)+(i-1)*md.numberofgrids2d pressureload_layer1(:,5)+(i-1)*md.numberofelements2d pressureload_layer1(:,6)];
+end
+
+%plug into md
+md.pressureload=pressureload;
+
+%materials
+md.rheology_B=project3d(md,md.rheology_B,'node');
+md.rheology_n=project3d(md,md.rheology_n,'element');
+
+%parameters
+md.surface=project3d(md,md.surface,'node');
+md.thickness=project3d(md,md.thickness,'node');
+md.bed=project3d(md,md.bed,'node');
+md.gridonboundary=project3d(md,md.gridonboundary,'node');
+md.elementoniceshelf=project3d(md,md.elementoniceshelf,'element');
+md.gridoniceshelf=project3d(md,md.gridoniceshelf,'node');
+md.elementonicesheet=project3d(md,md.elementonicesheet,'element');
+md.gridonicesheet=project3d(md,md.gridonicesheet,'node');
+md.elementonwater=project3d(md,md.elementonwater,'element');
+md.gridonwater=project3d(md,md.gridonwater,'node');
+if ~isnan(md.weights),md.weights=project3d(md,md.weights,'node');end;
+
+%Put lithostatic pressure is there is an existing pressure
+if ~isnan(md.pressure),
+	md.pressure=md.g*md.rho_ice*(md.surface-md.z);
+end
+
+%special for thermal modeling:
+md.melting_rate=project3d(md,md.melting_rate,'node',1); 
+md.observed_temperature=project3d(md,md.observed_temperature,'node'); 
+md.geothermalflux=project3d(md,md.geothermalflux,'node',1); %bedrock only gets geothermal flux
+
+%increase connectivity if less than 25:
+if md.connectivity<=25,
+	md.connectivity=100;
+end
+
+%augment counter  keeping track of what has been done to this model
+md.counter=4;
Index: /issm/trunk/src/m/model/geography.m
===================================================================
--- /issm/trunk/src/m/model/geography.m	(revision 5901)
+++ /issm/trunk/src/m/model/geography.m	(revision 5901)
@@ -0,0 +1,72 @@
+function md=geography(md,iceshelfname,icesheetname)
+%GEOGRAPHY - establish boundaries between grounded and floating ice.
+%
+%   By default, ice is considered grounded. The contour iceshelfname defines grids 
+%   for which ice is floating. The contour icesheetname defines grids inside an iceshelf, 
+%   that are grounded (ie: ice rises, islands, etc ...)
+%   All input files are in the Argus format (extension .exp).
+%
+%   Usage:
+%      md=geography(md,iceshelfname,icesheetname)
+%
+%   Examples:
+%      md=geography(md,'all','');
+%      md=geography(md,'Iceshelves.exp','Islands.exp');
+
+%some checks on list of arguments
+if ((nargin~=3) | (nargout~=1)),
+	help geography
+	error('geography error message');
+end
+
+if md.counter>=2,
+	choice=input('This model already has a geometry. Are you sure you want to go ahead? (y/n)','s');
+	if ~strcmp(choice,'y'), error('no geometry done ... exiting'); end
+else
+	if (md.counter~=1), error('geography error message: you need to run mesh.m first on this model'); end
+end
+
+%Get assigned fields
+x=md.x;
+y=md.y;
+elements=md.elements;
+
+elementoniceshelf=FlagElements(md,iceshelfname);
+elementonicesheet=FlagElements(md,icesheetname);
+
+%Because icesheet grids and elements can be included into an iceshelf, we need to update. Remember, all the previous 
+%arrays come from domain outlines that can intersect one another: 
+gridoniceshelf=zeros(md.numberofgrids,1);
+gridonicesheet=zeros(md.numberofgrids,1);
+elementoniceshelf=double((elementoniceshelf & ~elementonicesheet));
+elementonicesheet=double(~elementoniceshelf);
+gridoniceshelf(md.elements(find(elementoniceshelf),:))=1;
+gridonicesheet(md.elements(find(elementonicesheet),:))=1;
+
+%Return: 
+md.counter=2;
+
+md.elementoniceshelf=elementoniceshelf;
+md.gridoniceshelf=gridoniceshelf;
+
+md.elementonicesheet=elementonicesheet;
+md.gridonicesheet=gridonicesheet;
+
+md.gridonwater=zeros(md.numberofgrids,1);
+md.elementonwater=zeros(md.numberofelements,1);
+
+%Keep track of input files
+if (strcmp(iceshelfname,'') | strcmp(iceshelfname,'all')),
+	md.iceshelfoutline=iceshelfname;
+elseif ischar(iceshelfname),
+	md.iceshelfoutline=char(textread(iceshelfname,'%s','delimiter','\n'));
+else
+	md.iceshelfoutline=iceshelfname;
+end
+if (strcmp(icesheetname,'') | strcmp(icesheetname,'all')),
+	md.icesheetoutline=icesheetname;
+elseif ischar(icesheetname),
+	md.icesheetoutline=char(textread(icesheetname,'%s','delimiter','\n'));
+else 
+	md.icesheetoutline=icesheetname;
+end
Index: /issm/trunk/src/m/model/geography2.m
===================================================================
--- /issm/trunk/src/m/model/geography2.m	(revision 5901)
+++ /issm/trunk/src/m/model/geography2.m	(revision 5901)
@@ -0,0 +1,151 @@
+function md=geography2(md,landname,iceshelfname,icesheetname)
+%GEOGRAPHY2 - establish land, ice sheet and ice shelf areas in a domains.
+%
+%   Usage:
+%      md=geography2(md,landname,iceshelfname,icesheetname)
+%
+%   Examples:
+%      md=geography2(md,'LandName.exp','Iceshelves.exp','Islands.exp');
+
+%Get assigned fields
+x=md.x;
+y=md.y;
+elements=md.elements;
+
+%recover elements and grids on land.
+if ischar(landname),
+	[gridonland,elementonland]=ContourToMesh(elements,x,y,landname,'element and node',2);
+elseif isfloat(landname),
+	if size(landname,1)~=md.numberofelements,
+		error('Landname for area must be of same size as number of elements in model');
+	end
+	elementonland=landname;
+	gridonland=zeros(md.numberofgrids,1);
+	gridonland(md.elements(find(elementonland),:))=1;
+else
+	error('Invalid area option option');
+end
+
+%Now, build the connectivity tables for this mesh.
+if size(md.nodeconnectivity,1)~=md.numberofgrids,
+	md.nodeconnectivity=NodeConnectivity(md.elements,md.numberofgrids);
+end
+if size(md.elementconnectivity,1)~=md.numberofelements,
+	md.elementconnectivity=ElementConnectivity(md.elements,md.nodeconnectivity);
+end
+
+%any element with 3 grids on land should be on land:
+elementsonwater=find(~elementonland);
+wrongelements=elementsonwater(find(( gridonland(md.elements(elementsonwater,1)) + gridonland(md.elements(elementsonwater,2)) + gridonland(md.elements(elementsonwater,3)) ...
+                  )==3));
+elementonland(wrongelements)=1;
+
+%any element with its barycentre on land should be on land: (only if landname is an expfile)
+if ischar(landname),
+weights={[1;1;1],[2;1;1],[1;2;1],[1;1;2]};
+	for i=1:length(weights),
+		xelem=x(md.elements)*weights{i}/sum(weights{i});
+		yelem=y(md.elements)*weights{i}/sum(weights{i});
+	end
+	baryonland=ContourToNodes(xelem,yelem,landname,1);
+	pos=find(~baryonland); elementonland(pos)=0;
+	pos=find(baryonland); elementonland(pos)=1;
+end
+
+%figure out which elements on land are actually in the middle of the ocean!
+pos1=find(elementonland); 
+connectedtoland=md.elementconnectivity(pos1,:);
+pos=find(connectedtoland); connectedtoland(pos)=1-elementonland(connectedtoland(pos));
+connectedtolandsum=sum(connectedtoland,2);
+waterelements=pos1(find(connectedtolandsum==3));
+elementonland(waterelements)=0;
+
+%figure out which elements on water  are actually in the middle of the land!
+pos1=find(~elementonland); 
+connectedtowater=md.elementconnectivity(pos1,:);
+pos=find(connectedtowater); connectedtowater(pos)=elementonland(connectedtowater(pos));
+connectedtowatersum=sum(connectedtowater,2);
+landelements=pos1(find(connectedtowatersum==3));
+elementonland(landelements)=1;
+
+%recover arrays of ice shelf grids and elements, and ice sheet grids and elements.
+elementoniceshelf=FlagElements(md,iceshelfname);
+elementonicesheet=FlagElements(md,icesheetname);
+
+%Because icesheet grids and elements can be included into an iceshelf, we need to update. Remember, all the previous 
+%arrays come from domain outlines that can intersect one another: 
+gridoniceshelf=zeros(md.numberofgrids,1);
+gridonicesheet=zeros(md.numberofgrids,1);
+elementoniceshelf=double((elementoniceshelf & ~elementonicesheet));
+elementonicesheet=double(~elementoniceshelf);
+gridoniceshelf(md.elements(find(elementoniceshelf),:))=1;
+gridonicesheet(md.elements(find(elementonicesheet),:))=1;
+
+%now correct, so that none of the iceshelf and icesheet elements and nodes are in the water.
+pos=find(~elementonland);
+elementoniceshelf(pos)=0; 
+elementonicesheet(pos)=0;
+
+pos=find(~gridonland);
+gridoniceshelf(pos)=0; 
+gridonicesheet(pos)=0;
+
+%create gridonwater and elementonwater: 
+gridonwater=double(~gridonland);
+elementonwater=double(~elementonland);
+
+%correct for islands:
+gridoniceshelf=double(gridoniceshelf & ~gridonicesheet);
+elementoniceshelf=double(elementoniceshelf & ~elementonicesheet);
+
+%now, icesheets are everything except iceshelves and water
+gridonicesheet=double(~gridoniceshelf & ~gridonwater);
+elementonicesheet=double(~elementoniceshelf & ~elementonwater);
+
+%Deal with segments on neumann:
+
+%Get current connectivity
+elementconnectivity=md.elementconnectivity;
+
+%put 0 for elements on water
+pos=find(elementconnectivity);
+elementconnectivity(pos)=elementconnectivity(pos).*(~elementonwater(elementconnectivity(pos)));
+
+%put line of ones for elements on water
+pos=find(elementonwater);
+elementconnectivity(pos,:)=1;% line of ones for elements on water so they won't be considered
+
+%resort lines (zeros must be at the last column for findsegments)
+elementconnectivity=sort(elementconnectivity,2,'descend');
+
+%call findsegments to build segment using THIS conectivity
+md.segments=findsegments(md,'elementconnectivity',elementconnectivity);
+
+%some final checks: 
+%check that no grid thinks it's on an ice shelf or ice sheet, and lies actually in the middle of the water.
+gridsgrounded=find(~gridonwater);
+lengthconnectivity=size(md.nodeconnectivity,2);
+groundedcounters=md.nodeconnectivity(gridsgrounded,lengthconnectivity);
+groundedconnectivity=md.nodeconnectivity(gridsgrounded,1:lengthconnectivity-1);
+pos=find(groundedconnectivity);
+groundedconnectivity(pos)=elementonwater(groundedconnectivity(pos));
+groundedsum=sum(groundedconnectivity,2);
+errorflags=find(groundedsum==groundedcounters);
+errorgrids=gridsgrounded(errorflags);
+
+gridonwater(errorgrids)=1;
+gridonicesheet(errorgrids)=0;
+gridoniceshelf(errorgrids)=0;
+
+%Return: 
+md.gridoniceshelf=gridoniceshelf;
+md.elementoniceshelf=elementoniceshelf;
+
+md.gridonwater=gridonwater;
+md.elementonwater=elementonwater;
+
+md.gridonicesheet=gridonicesheet;
+md.elementonicesheet=elementonicesheet;
+
+md.counter=2;
+md.segmentmarkers(:)=1;
Index: /issm/trunk/src/m/model/graddetection.m
===================================================================
--- /issm/trunk/src/m/model/graddetection.m	(revision 5901)
+++ /issm/trunk/src/m/model/graddetection.m	(revision 5901)
@@ -0,0 +1,33 @@
+function [direction,direction2]=graddetection(md)
+%GRADDETECTION detect gradient of control method between steps nsteps+1 and nsteps
+%
+% Usage: direction=graddetection(md);
+
+%keep copy of md: 
+md2=md;
+
+%solve first batch of control methods, with given settings.
+md2=solve(md2,'analysis_type','DiagnosticAnalysis');
+
+%record final optimized parameter. 
+parameter1=md2.results.DiagnosticAnalysis.parameter;
+
+%plug optimized parameter in model. 
+md2.(EnumToModelField(md2.results.DiagnosticAnalysis.control_type))=parameter1;
+
+%put nsteps to 1: 
+md2.nsteps=1;
+md2.optscal=md2.optscal(end)*ones(md2.nsteps,1);
+md2.fit=md2.fit(end)*ones(md2.nsteps,1);
+md2.cm_jump=md2.cm_jump(end)*ones(md2.nsteps,1);
+md2.maxiter=md2.maxiter(end)*ones(md2.nsteps,1);
+
+%rerun control method with optimized parameter, only for 1 more step.
+md2=solve(md2,'analysis_type','DiagnosticAnalysis');
+
+%get optimized parameter after 1 more step. 
+parameter2=md2.results.DiagnosticAnalysis.parameter;
+
+%return relative  difference between nsteps+1 and nsteps;
+direction=(parameter2-parameter1)./parameter1;
+direction2=(parameter2-parameter1);
Index: /issm/trunk/src/m/model/ismodelselfconsistent.m
===================================================================
--- /issm/trunk/src/m/model/ismodelselfconsistent.m	(revision 5901)
+++ /issm/trunk/src/m/model/ismodelselfconsistent.m	(revision 5901)
@@ -0,0 +1,549 @@
+function ismodelselfconsistent(md),
+%ISMODELSELFCONSISTENT - check that model forms a closed form solvable problem.
+%
+%   Usage:
+%      ismodelselfconsistent(md),
+
+%tolerance we use in litmus checks for the consistency of the model
+tolerance=10^-9;
+%check usage {{{1
+if nargin~=1,
+	help ismodelselfconsistent
+	error('ismodelselfconsistent error message: wrong usage');
+end
+%}}}
+
+%recursive call for TRANSIENT {{{1
+if (md.analysis_type==Transient2DSolutionEnum | md.analysis_type==Transient3DSolutionEnum),
+	if md.dt<=0,
+		error('model not consistent: field dt must be positive for a transient run')
+	end
+
+	%recursive call to ismodelselfconsistent
+	if (md.dim==2),
+		analysis=[DiagnosticSolutionEnum PrognosticSolutionEnum];
+	else
+		analysis=[DiagnosticSolutionEnum PrognosticSolutionEnum ThermalSolutionEnum];
+	end
+
+	for i=1:length(analysis),
+		md.analysis_type=analysis(i);
+		ismodelselfconsistent(md);
+	end
+end
+%}}}
+
+% Common checks
+%COUNTER {{{1
+if md.counter<3,
+	error(['model ' md.name ' is not correctly configured. You forgot one step in the following sequence (mesh, geography, parameterize,setelementstype)!']);
+end
+%}}}
+%NAME{{{1
+if isempty(md.name),
+	error(['model is not correctly configured: missing name!']);
+end
+%}}}
+%ELEMENTS{{{1
+fields={'elements'};
+if (md.dim==2),
+	checksize(md,fields,[md.numberofelements 3]);
+else
+	checksize(md,fields,[md.numberofelements 6]);
+end
+%}}}
+%ELEMENTSTYPE{{{1
+%Check the size of elements_type
+fields={'elements_type'};
+checksize(md,fields,[md.numberofelements 1]);
+%Check the values of elements_type
+checkvalues(md,{'elements_type'},[MacAyealApproximationEnum() HutterApproximationEnum() PattynApproximationEnum() MacAyealPattynApproximationEnum() PattynStokesApproximationEnum() StokesApproximationEnum() NoneApproximationEnum()]);
+if (md.dim==2),
+	checkvalues(md,{'elements_type'},[MacAyealApproximationEnum() HutterApproximationEnum()]);
+end
+if (md.ismacayealpattyn==0 && md.ishutter==0 && md.isstokes==0),
+	error(['model not consistent: no elements type set for this model. at least one of ismacayealpattyn, ishutter and isstokes need to be =1']);
+end
+%}}}
+%VERTICESTYPE{{{1
+%Check the size of verticess_type
+fields={'vertices_type'};
+checksize(md,fields,[md.numberofgrids 1]);
+%Check the values of vertices_type
+checkvalues(md,{'vertices_type'},[MacAyealApproximationEnum() HutterApproximationEnum() PattynApproximationEnum() MacAyealPattynApproximationEnum() StokesApproximationEnum() NoneApproximationEnum()]);
+if (md.dim==2),
+	checkvalues(md,{'vertices_type'},[MacAyealApproximationEnum() HutterApproximationEnum()]);
+end
+if (md.ismacayealpattyn==0 && md.ishutter==0 && md.isstokes==0),
+	error(['model not consistent: no elements type set for this model. at least one of ismacayealpattyn, ishutter and isstokes need to be =1']);
+end
+%}}}
+%DG {{{1
+if md.prognostic_DG==1;
+	%CHECK THE COMPATIBILITY OF THE EDGES
+	fields={'edges'};
+	checksize(md,fields,[NaN 4]);
+	fields={'edges(:,1:3)'};
+	checknan(md,fields);
+	checkgreaterstrict(md,fields,0);
+end
+%}}}
+%PRESSURELOAD{{{1
+if (md.dim==2),
+	fields={'pressureload'};
+	checksize(md,fields,[NaN 4]);
+elseif md.dim==3,
+	fields={'pressureload'};
+	checksize(md,fields,[NaN 6]);
+else
+	error('dim should be either 2 3');
+end
+checkvalues(md,{'pressureload(:,end)'},[WaterEnum() AirEnum()]);
+%}}}
+%NO NAN {{{1
+fields={'numberofelements','numberofgrids','x','y','z','drag_coefficient','drag_type','drag_p','drag_q',...
+	'rho_ice','rho_water','rheology_B','elementoniceshelf','surface','thickness','bed','g','lowmem','sparsity','nsteps','maxiter',...
+	'tolx','np','eps_res','max_nonlinear_iterations','exclusive','rheology_n','gridonbed','gridonsurface','elementonbed','elementonsurface','deltaH','DeltaH','timeacc','timedec'};
+checknan(md,fields);
+%}}}}
+%FIELDS >= 0 {{{1
+fields={'numberofelements','numberofgrids','elements','drag_coefficient','drag_type','drag_p','drag_q',...
+	'rho_ice','rho_water','rheology_B','elementoniceshelf','thickness','g','eps_res','max_nonlinear_iterations','eps_rel','eps_abs','nsteps','maxiter','tolx','exclusive',...
+	'sparsity','lowmem','rheology_n','gridonbed','gridonsurface','elementonbed','elementonsurface','deltaH','DeltaH','timeacc','timedec'};
+checkgreater(md,fields,0);
+%}}}
+%FIELDS > 0 {{{1
+fields={'numberofelements','numberofgrids','elements','drag_type','drag_p',...
+	'rho_ice','rho_water','rheology_B','thickness','g','max_nonlinear_iterations','eps_res','eps_rel','eps_abs','maxiter','tolx',...
+	'sparsity','deltaH','DeltaH','timeacc','timedec'};
+checkgreaterstrict(md,fields,0);
+%}}}
+%SIZE NUMBEROFELEMENTS {{{1
+fields={'drag_p','drag_q','elementoniceshelf','rheology_n','elementonbed'};
+checksize(md,fields,[md.numberofelements 1]);
+%}}}
+%SIZE NUMBEROFGRIDS {{{1
+fields={'x','y','z','rheology_B','drag_coefficient','melting_rate','accumulation_rate','surface','thickness','bed','gridonbed','gridonsurface'};
+checksize(md,fields,[md.numberofgrids 1]);
+%}}}
+%OTHER SIZES {{{1
+fields={'spcvelocity'};
+checksize(md,fields,[md.numberofgrids 6]);
+%}}}
+%THICKNESS = SURFACE - BED {{{1
+if any((md.thickness-md.surface+md.bed)>tolerance),
+	error(['model not consistent: model ' md.name ' violates the equality thickness=surface-bed!']);
+end
+%}}}
+%RIFTS{{{1
+if md.numrifts,
+	if ~(md.dim==2),
+		error(['model not consistent: models with rifts are only supported in 2d for now!']);
+	end
+	if ~isstruct(md.rifts),
+		error(['model not consistent: md.rifts should be a structure!']);
+	end
+	if ~isempty(find(md.segmentmarkers>=2)),
+		%We have segments with rift markers, but no rift structure!
+		error(['model not consistent: model ' md.name ' should be processed for rifts (run meshprocessrifts)!']);
+	end
+	%Check that rifts are filled with proper material
+	checkvalues(md,{'rifts.fill'},[WaterEnum() AirEnum() IceEnum() MelangeEnum()]);
+else
+	if ~isnans(md.rifts),
+		error(['model not consistent: md.rifts shoud be NaN since md.numrifts is 0!']);
+	end
+end
+%}}}
+%FLAGS (0 or 1){{{1
+if ~ismember(md.artificial_diffusivity,[0 1]),
+	error('model not consistent: artificial_diffusivity should be a scalar (1 or 0)');
+end
+if ~ismember(md.prognostic_DG,[0 1]),
+	error('model not consistent: prognostic_DG should be a scalar (1 or 0)');
+end
+if ~ismember(md.lowmem,[0 1]),
+	error(['model not consistent: model ' md.name ' lowmem field should be 0 or 1']);
+end
+%}}}
+%SCALAR
+if ~isscalar(md.control_type),
+	error('model not consistent: md.control_type should be a scalar');
+end
+%}}}
+%PARAMETEROUTPUT {{{1
+if md.numoutput~=length(md.parameteroutput),
+	error('model not consistent: numoutput should be the same size as parameteroutput');
+end
+%}}}
+%CONNECTIVITY {{{1
+if (md.dim==2),
+	if md.connectivity<9, 
+		error('model not consistent: connectivity should be at least 9 for 2d models');
+	end
+end
+if md.dim==3,
+	if md.connectivity<24, 
+		error('model not consistent: connectivity should be at least 24 for 3d models');
+	end
+end
+%}}}
+%PARALLEL{{{1
+if ~strcmpi(md.cluster,'none'),
+
+	%NAN VALUES
+	fields={'time','np'};
+	checknan(md,fields);
+
+	%FIELD > 0
+	fields={'time','np'};
+	checkgreaterstrict(md,fields,0);
+
+end
+%}}}
+
+% Solution checks
+%DIAGNOSTIC{{{1
+if md.analysis_type==DiagnosticSolutionEnum,
+
+	%HUTTER ON ICESHELF WARNING
+	if any(md.elements_type==HutterApproximationEnum & md.elementoniceshelf),
+		disp(sprintf('\n !!! Warning: Hutter''s model is not consistent on ice shelves !!!\n'));
+	end
+
+	%SINGULAR
+	if ~any(sum(md.spcvelocity(:,1:2),2)==2),
+		error(['model not consistent: model ' md.name ' is not well posed (singular). You need at least one grid with fixed velocity!'])
+	end
+
+	%DIRICHLET IF THICKNESS <= 0
+	if any(md.thickness<=0),
+		pos=find(md.thickness<=0);
+		if any(find(md.spcthickness(pos,1)==0)),
+			error(['model not consistent: model ' md.name ' has some grids with 0 thickness']);
+		end
+	end
+
+	%INITIAL VELOCITY
+	if length(md.vx)==md.numberofgrids & length(md.vy)==md.numberofgrids,
+		fields={'vx','vy'};
+		checknan(md,fields);
+	end
+end
+%}}}
+%PROGNOSTIC{{{1
+if md.analysis_type==PrognosticSolutionEnum,
+
+	%INITIAL VELOCITIES
+	fields={'vx','vy'};
+	checksize(md,fields,[md.numberofgrids 1]);
+	checknan(md,fields);
+
+	%CHECK THAT WE ARE NOT FULLY CONSTRAINED
+	if (md.dim==2),
+		if isempty(find(~md.spcthickness(:,1))),
+			error(['model not consistent: model ' md.name ' is totally constrained for prognostic, no need to solve!']);
+		end
+	end
+
+end
+%}}}
+%STEADYSTATE{{{1
+if md.analysis_type==SteadystateSolutionEnum,
+
+	%NDT
+	if md.dt~=0,
+		error(['model not consistent: for a steadystate computation, dt must be zero.']);
+	end
+
+	%PRESSURE
+	if isnans(md.pressure),
+		error(['model not consistent: for a steadystate computation, the model must have an initial pressure, even lithostatic will do.']);
+	end
+
+	%eps: 
+	if isnan(md.eps_rel),
+		error(['model not consistent: for a steadystate computation, eps_rel (relative convergence criterion) must be defined!']);
+	end
+
+	%dim: 
+	if (md.dim==2),
+		error(['model not consistent: for a steadystate computation, model needs to be 3d']);
+	end
+end
+%}}}
+%THERMAL {{{1
+%THERMAL STEADY AND THERMAL TRANSIENT
+if md.analysis_type==ThermalSolutionEnum,
+
+	%EXTRUSION
+	if (md.dim==2),
+		error(['model not consistent: for a ' md.analysis_type ' computation, the model must be 3d, extrude it first!'])
+	end
+
+	%CHECK THAT WE ARE NOT FULLY CONSTRAINED
+	if isempty(find(~md.spctemperature(:,1))),
+		error(['model not consistent: model ' md.name ' is totally constrained for temperature, no need to solve!']);
+	end
+
+	%VELOCITIES AND PRESSURE
+	fields={'vx','vy','vz','pressure'};
+	checksize(md,fields,[md.numberofgrids 1]);
+	checknan(md,fields);
+
+end
+
+%THERMAL TRANSIENT
+if md.analysis_type==ThermalSolutionEnum & md.dt~=0,
+
+	%DT and NDT
+	fields={'dt','ndt'};
+	checkgreaterstrict(md,fields,0);
+
+	%INITIAL TEMPERATURE, MELTING AND ACCUMULATION
+	fields={'temperature','accumulation_rate','melting_rate'};
+	checksize(md,fields,[md.numberofgrids 1]);
+	checknan(md,fields);
+
+	%INITIAL TEMPERATURE
+	fields={'temperature','spctemperature(:,2)','observed_temperature'};
+	checkgreater(md,fields,0)
+
+end
+%}}}
+%BALANCEDTHICKNESS{{{1
+if md.analysis_type==BalancedthicknessSolutionEnum
+
+	%VELOCITIES MELTING AND ACCUMULATION
+	fields={'vx','vy','accumulation_rate','melting_rate','dhdt'};
+	checksize(md,fields,[md.numberofgrids 1]);
+	checknan(md,fields);
+
+	%SPC				 
+	if ~md.prognostic_DG,
+		if any(md.spcthickness(find(md.gridonboundary))~=1),		 
+			error(['model not consistent: model ' md.name ' should have all the nodes on boundary constrained in field spcthickness']);			 
+		end 
+	end
+
+	%Triangle with zero velocity
+	if any(sum(abs(md.vx(md.elements)),2)==0 & sum(abs(md.vy(md.elements)),2)==0)
+		error('model not consistent: at least one triangle has all its vertices with a zero velocity');
+	end
+end
+%}}}
+%BALANCEDVELOCITIES{{{1
+if md.analysis_type==BalancedvelocitiesSolutionEnum
+
+	%VELOCITIES MELTING AND ACCUMULATION
+	fields={'vx','vy','accumulation_rate','melting_rate'};
+	checksize(md,fields,[md.numberofgrids 1]);
+	checknan(md,fields);
+
+	%SPC
+	if any(md.spcvelocity(find(md.gridonboundary),[1:2])~=1),
+		error(['model not consistent: model ' md.name ' should have all the nodes on boundary constrained in field spcvelocity']);
+	end
+end
+%}}}
+%CONTROL{{{1
+if md.control_analysis,
+
+	%CONTROL TYPE
+	if ~isnumeric(md.control_type),
+		error('model not consistent: control_type should be an enum');
+	end
+	checkvalues(md,{'control_type'},[DhDtEnum DragCoefficientEnum RheologyBbarEnum]);
+
+	%LENGTH CONTROL FIELDS
+	fields={'maxiter','optscal','cm_responses','cm_jump'};
+	checksize(md,fields,[md.nsteps 1]);
+
+	%RESPONSES
+	checkvalues(md,{'cm_responses'},[SurfaceAbsVelMisfitEnum SurfaceRelVelMisfitEnum SurfaceLogVelMisfitEnum SurfaceLogVxVyMisfitEnum SurfaceAverageVelMisfitEnum ThicknessAbsMisfitEnum]);
+
+	%WEIGHTS
+	fields={'weights'};
+	checksize(md,fields,[md.numberofgrids 1]);
+	checkgreater(md,fields,0);
+
+	%OBSERVED VELOCITIES
+	if md.analysis_type==BalancedthicknessSolutionEnum
+		fields={'thickness_obs'};
+		checksize(md,fields,[md.numberofgrids 1]);
+		checknan(md,fields);
+	else
+		fields={'vx_obs','vy_obs'};
+		checksize(md,fields,[md.numberofgrids 1]);
+		checknan(md,fields);
+	end
+
+	%DIRICHLET IF THICKNESS <= 0
+	if any(md.thickness<=0),
+		pos=find(md.thickness<=0);
+		if any(find(md.spcthickness(pos,1)==0)),
+			error(['model not consistent: model ' md.name ' has some grids with 0 thickness']);
+		end
+	end
+
+	%parameters
+	fields={'cm_noisedmp'};
+	checknan(md,fields);
+end
+%}}}
+%QMU {{{1
+if md.qmu_analysis,
+	if md.qmu_params.evaluation_concurrency~=1,
+		error(['model not consistent: concurrency should be set to 1 when running dakota in library mode']);
+	end
+	if ~isempty(md.part),
+		if numel(md.part)~=md.numberofgrids,
+			error(['model not consistent: user supplied partition for qmu analysis should have size md.numberofgrids x 1 ']);
+		end
+		if find(md.part)>=md.numberofgrids,
+			error(['model not consistent: user supplied partition should be indexed from 0 (c-convention)']);
+		end
+		if min(md.part)~=0,
+			error(['model not consistent: partition vector not indexed from 0 on']);
+		end
+		if max(md.part)>=md.numberofgrids,
+			error(['model not consistent: partition vector cannot have maximum index larger than number of grids']);
+		end
+		if ~isempty(find(md.part<0)),
+			error(['model not consistent: partition vector cannot have values less than 0']);
+		end
+		if ~isempty(find(md.part>=md.npart)),
+			error(['model not consistent: partition vector cannot have values more than md.npart-1']);
+		end
+		if max(md.part)>=md.npart,
+			error(['model not consistent: for qmu analysis, partitioning vector cannot go over npart, number of partition areas']);
+		end
+	end
+	if ~md.qmu_relax,
+		if md.eps_rel>1.1*10^-5,
+			error(['model not consistent: for qmu analysis, eps_rel should be least than 10^-5, 10^-15 being a better value']);
+		end
+	end
+end
+
+if strcmpi(md.analysis_type,'qmu'),
+	if ~strcmpi(md.cluster,'none'),
+		if md.waitonlock==0,
+			error(['model is not correctly configured: waitonlock should be activated when running qmu in parallel mode!']);
+		end
+	end
+end
+%}}}
+
+end
+
+%checks additional functions
+%checklength {{{1
+function checklength(md,fields,fieldlength)
+	%CHECKSIZE - check length of a field
+	for i=1:length(fields),
+		eval(['field=md.' fields{i} ';']);
+		if length(field)~=fieldlength,
+			error(['model not consistent: field ' fields{i} ' length should be ' num2str(fieldlength)]);
+		end
+	end
+end
+%}}}
+%checksize {{{1
+function checksize(md,fields,fieldsize)
+	%CHECKSIZE - check size of a field
+	for i=1:length(fields),
+		eval(['field=md.' fields{i} ';']);
+		if isnan(fieldsize(1)),
+			if (size(field,2)~=fieldsize(2)),
+				error(['model not consistent: field ' fields{i} ' should have ' num2str(fieldsize(2)) ' columns']);
+			end
+		elseif isnan(fieldsize(2)),
+			if (size(field,1)~=fieldsize(1)),
+				error(['model not consistent: field ' fields{i} ' should have ' num2str(fieldsize(1)) ' rows']);
+			end
+		else
+			if ((size(field)~=fieldsize(1)) |  (size(field,2)~=fieldsize(2)))
+				error(['model not consistent: field ' fields{i} ' size should be ' num2str(fieldsize(1)) ' x ' num2str(fieldsize(2))]);
+			end
+		end
+	end
+end
+%}}}
+%checknan {{{1
+function checknan(md,fields)
+	%CHECKNAN - check nan values of a field
+	for i=1:length(fields),
+		eval(['field=reshape(md.' fields{i} ',[prod(size(md.' fields{i} ')) 1]);']);
+		if any(isnan(field)),
+			error(['model not consistent: NaN values found in field ' fields{i}]);
+		end
+	end
+end
+%}}}
+%checkreal{{{1
+function checkreal(md,fields)
+	%CHECKREAL - check real values of a field
+	for i=1:length(fields),
+		eval(['field=reshape(md.' fields{i} ',[prod(size(md.' fields{i} ')) 1]);']);
+		if any(~isreal(field)),
+			error(['model not consistent: complex values found in field ' fields{i}]);
+		end
+	end
+end
+%}}}
+%checkgreaterstrict{{{1
+function checkgreaterstrict(md,fields,lowerbound)
+	%CHECKGREATERSTRICT - check values of a field
+	for i=1:length(fields),
+		eval(['field=reshape(md.' fields{i} ',[prod(size(md.' fields{i} ')) 1]);']);
+		if any(field<=lowerbound),
+			error(['model not consistent: field ' fields{i} ' should have values stricly above ' num2str(lowerbound)]);
+		end
+	end
+end
+%}}}
+%checkgreater{{{1
+function checkgreater(md,fields,lowerbound)
+	%CHECKGREATER - check values of a field
+	for i=1:length(fields),
+		eval(['field=reshape(md.' fields{i} ',[prod(size(md.' fields{i} ')) 1]);']);
+		if any(field<lowerbound),
+			error(['model not consistent: field ' fields{i} ' should have values above ' num2str(lowerbound)]);
+		end
+	end
+end
+%}}}
+%checklessstrict{{{1
+function checklessstrict(md,fields,upperbound)
+	%CHECKLESSSTRICT - check values of a field
+	for i=1:length(fields),
+		eval(['field=reshape(md.' fields{i} ',[prod(size(md.' fields{i} ')) 1]);']);
+		if any(field>=upperbound),
+			error(['model not consistent: field ' fields{i} ' should have values stricly below ' num2str(upperbound)]);
+		end
+	end
+end
+%}}}
+%checkless{{{1
+function checkless(md,fields,upperbound)
+	%CHECKLESS - check values of a field
+	for i=1:length(fields),
+		eval(['field=reshape(md.' fields{i} ',[prod(size(md.' fields{i} ')) 1]);']);
+		if any(field>upperbound),
+			error(['model not consistent: field ' fields{i} ' should have values below ' num2str(upperbound)]);
+		end
+	end
+end
+%}}}
+%checkvalues {{{1
+function checkvalues(md,fields,values)
+	%CHECKVALUE - check that a field has specified values
+	for i=1:length(fields),
+		eval(['field=reshape(md.' fields{i} ',[prod(size(md.' fields{i} ')) 1]);']);
+		if any(~ismember(field,values)),
+			error(['model not consistent: field ' fields{i} ' should have values in ' num2str(values)]);
+		end
+	end
+end
+%}}}
Index: /issm/trunk/src/m/model/isresultconsistent.m
===================================================================
--- /issm/trunk/src/m/model/isresultconsistent.m	(revision 5901)
+++ /issm/trunk/src/m/model/isresultconsistent.m	(revision 5901)
@@ -0,0 +1,249 @@
+function bool=isresultconsistent(md,analysis_type)
+%ISRESULTCONSISTENT: check that results are consistent
+%
+%   This routine is called after a computation and check
+%   that the values t the penalties are consitent
+%
+%   Usage:
+%      bool=IsModelSelfConsistent(model,analysis_type)
+
+%tolerance we use in litmus tests for the consistency of the model
+tolerance=10^-2;
+
+%some checks
+if (nargin~=2 | nargout~=1)
+	help isresultconsistent
+	error(' ');
+end
+
+%initialize output as 1 -> success
+bool=1;
+
+%do not check results if qmu analysis
+if md.qmu_analysis,
+	return
+end
+
+%DIAGNOSTIC
+if analysis_type==DiagnosticSolutionEnum() & md.control_analysis==0,
+
+	if (md.dim==3)
+		fields1={'results.DiagnosticAnalysis.vx','results.DiagnosticAnalysis.vy','results.DiagnosticAnalysis.vz','results.DiagnosticAnalysis.vel'};
+		fields2={'results.DiagnosticAnalysis.vel'};
+	else
+		fields1={'results.DiagnosticAnalysis.vx','results.DiagnosticAnalysis.vy','results.DiagnosticAnalysis.vel'};
+		fields2={'results.DiagnosticAnalysis.vel'};
+	end
+
+	%check size
+	if ~testsize(md,fields1,md.numberofgrids),
+		bool=0; return
+	end
+
+	%no NAN
+	if ~testnan(md,fields1),
+		bool=0; return
+	end
+
+	%check value is real
+	if ~testreal(md,fields1),
+		bool=0; return
+	end
+
+	%check value>=0
+	if ~testpositive(md,fields2),
+		bool=0; return
+	end
+
+end
+
+%CONTROL
+if analysis_type==DiagnosticSolutionEnum() & md.control_analysis==1,
+
+	if ~md.cm_gradient,
+		fields1={'results.DiagnosticAnalysis.vx','results.DiagnosticAnalysis.vy','results.DiagnosticAnalysis.vel','results.DiagnosticAnalysis.parameter'};
+		fields2={'results.DiagnosticAnalysis.vel','results.DiagnosticAnalysis.J'};
+
+		%check size
+		if ~testsize(md,fields1,md.numberofgrids),
+			bool=0; return
+		end
+
+		%no NAN
+		if ~testnan(md,fields1),
+			bool=0; return
+		end
+
+		%check value is real
+		if ~testreal(md,fields1),
+			bool=0; return
+		end
+
+		%check value>=0
+		if ~testpositive(md,fields2),
+			bool=0; return
+		end
+
+		%check inversed parameter
+		if ~isnan(md.cm_max),
+			if any(md.results.DiagnosticAnalysis.parameter>md.cm_max)
+				disp(['''control'' result not consistent: inverse parameter is greater than ' num2str(md.cm_max)]);
+				bool=0; return; 
+			end
+		end
+		if ~isnan(md.cm_min),
+			if any(md.results.DiagnosticAnalysis.parameter<md.cm_min)
+				disp(['''control'' result not consistent: inverse parameter is smaller than ' num2str(md.cm_min)]);
+				bool=0; return; 
+			end
+		end
+	else
+		fields={'results.DiagnosticAnalysis.gradient'};
+		%check size
+		if ~testsize(md,fields,md.numberofgrids),
+			bool=0; return
+		end
+
+		%no NAN
+		if ~testnan(md,fields),
+			bool=0; return
+		end
+
+		%check value is real
+		if ~testreal(md,fields),
+			bool=0; return
+		end
+	end
+end
+
+%THERMAL
+if analysis_type==ThermalSolutionEnum(),
+
+	for iter=1:length(md.results.ThermalAnalysis)
+
+		fields1={['results.ThermalAnalysis(' num2str(iter) ').temperature'],['results.ThermalAnalysis(' num2str(iter) ').melting']};
+		fields2={['results.ThermalAnalysis(' num2str(iter) ').temperature']};
+
+		%check size
+		if ~testsize(md,fields1,md.numberofgrids),
+			bool=0; return
+		end
+
+		%no NAN
+		if ~testnan(md,fields1,md.numberofgrids),
+			bool=0; return
+		end
+
+		%check value is real
+		if ~testreal(md,fields1,md.numberofgrids),
+			bool=0; return
+		end
+
+		%check value>=0
+		if ~testpositive(md,fields2,md.numberofgrids),
+			bool=0; return
+		end
+
+		%check melting (<=0 via penalties)
+		if any(abs(md.results.ThermalAnalysis(iter).melting(md.numberofgrids2d+1:end))>tolerance)
+			disp(['''thermal'' result not consistent: increase penalty_melting (negative melting)']);
+			bool=0; return; 
+		end
+	end
+
+end
+
+if (analysis_type==Transient2DSolutionEnum() | analysis_type==Transient3DSolutionEnum()),
+
+	for iter=1:length(md.results.TransientAnalysis)
+
+		if (md.dim==3),
+			fields1={['results.TransientAnalysis(' num2str(iter) ').vx'],['results.TransientAnalysis(' num2str(iter) ').vy'],...
+				['results.TransientAnalysis(' num2str(iter) ').vz'],['results.TransientAnalysis(' num2str(iter) ').vel'],...
+				['results.TransientAnalysis(' num2str(iter) ').bed'],['results.TransientAnalysis(' num2str(iter) ').surface'],...
+				['results.TransientAnalysis(' num2str(iter) ').thickness'],...
+				['results.TransientAnalysis(' num2str(iter) ').temperature'],['results.TransientAnalysis(' num2str(iter) ').melting']};
+			fields2={['results.TransientAnalysis(' num2str(iter) ').vel'],['results.TransientAnalysis(' num2str(iter) ').thickness'],...
+				['results.TransientAnalysis(' num2str(iter) ').temperature']};
+		else
+			fields1={['results.TransientAnalysis(' num2str(iter) ').vx'],['results.TransientAnalysis(' num2str(iter) ').vy'],...
+				['results.TransientAnalysis(' num2str(iter) ').vel'],...
+				['results.TransientAnalysis(' num2str(iter) ').bed'],['results.TransientAnalysis(' num2str(iter) ').surface'],...
+				['results.TransientAnalysis(' num2str(iter) ').thickness']};
+			fields2={['results.TransientAnalysis(' num2str(iter) ').vel'],['results.TransientAnalysis(' num2str(iter) ').thickness']};
+		end
+
+		%check size
+		if ~testsize(md,fields1,md.numberofgrids),
+			bool=0; return
+		end
+
+		%no NAN
+		if ~testnan(md,fields1,md.numberofgrids),
+			bool=0; return
+		end
+
+		%check value is real
+		if ~testreal(md,fields1,md.numberofgrids),
+			bool=0; return
+		end
+
+		%check value>=0
+		if ~testpositive(md,fields2,md.numberofgrids),
+			bool=0; return
+		end
+
+		%check melting (<=0 via penalties)
+		if (md.dim==3),
+			if any(abs(md.results.TransientAnalysis(iter).melting(md.numberofgrids2d+1:end))>tolerance)
+				disp(['''thermal'' result not consistent: increase penalty_melting (negative melting)']);
+				bool=0; return; 
+			end
+		end
+	end
+end
+end % end function
+
+function bool=testsize(md,fields,fieldsize)
+	%TESTSIZE - test size of a field
+	bool=1;
+	for i=1:length(fields),
+		if length(eval(['md.' fields{i}]))~=fieldsize
+			disp(['results not consistent: field ' fields{i} ' size should be ' num2str(md.numberofgrids)]);
+			bool=0; return;
+		end
+	end
+end
+
+function bool=testnan(md,fields,nanfield)
+	%TESTNAN - test nan values of a field
+	bool=1;
+	for i=1:length(fields),
+		if any(isnan(eval(['md.' fields{i}]))),
+			disp(['results not consistent: NaN values in field ' fields{i}]);
+			bool=0; return;
+		end
+	end
+end
+
+function bool=testreal(md,fields,realfield)
+	%TESTREAL - test real values of a field
+	bool=1;
+	for i=1:length(fields),
+		if any(eval(['~isreal(md.' fields{i} ')'])),
+			disp(['results not consistent: complex values in field ' fields{i}]);
+			bool=0; return;
+		end
+	end
+end
+
+function bool=testpositive(md,fields,positivefield)
+	%TESTPOSITIVE - test positive values of a field
+	bool=1;
+	for i=1:length(fields),
+		if any(eval(['md.' fields{i} '<0'])),
+			disp(['results not consistent: negative values in field ' fields{i}]);
+			bool=0; return;
+		end
+	end
+end
Index: /issm/trunk/src/m/model/loadmultipleresultsfromcluster.m
===================================================================
--- /issm/trunk/src/m/model/loadmultipleresultsfromcluster.m	(revision 5901)
+++ /issm/trunk/src/m/model/loadmultipleresultsfromcluster.m	(revision 5901)
@@ -0,0 +1,39 @@
+function md_list=loadmultipleresultsfromcluster(md_list)
+%LOADMULTIPLERESULTSFROMCLUSTER - load multiple results of solution sequences from cluster
+%
+%   Usage:
+%      md_list=loadresultsfromcluster(md_list);
+
+nummodels=length(md_list);
+
+%Get cluster settings
+cluster=md_list{1}.cluster;
+name=md_list{1}.name;
+cluster_rc_location=which('cluster.rc');
+[codepath,executionpath,login]=ClusterParameters(cluster,cluster_rc_location);
+
+%Remote tar: 
+disp('tarring results');
+issmssh(cluster,['"cd ' executionpath ' && rm -rf file_list.txt ModelResults.tar.gz && find -iname ''*_*vs*.outbin'' > file_list.txt && tar zcvf ModelResults.tar.gz --files-from file_list.txt  && rm -rf file_list.txt "']);
+
+%copy results from cluster to present directory
+scpin(cluster, executionpath, {'ModelResults.tar.gz'});
+
+%untar:
+!tar -zxvf ModelResults.tar.gz
+
+%ok, go through list and load results from disk: 
+for i=1:nummodels,
+	%load  results for this model
+	%md_list{i}.analysis_type=DiagnosticAnalysisEnum();
+	%md_list{i}.sub_analysis_type=NoneAnalysisEnum();
+	%md_list{i}=loadresultsfromdisk(md_list{i},[md_list{i}.name '_' num2str(i) 'vs' num2str(nummodels) '.outbin']);
+	md_list{i}=loadresultsfromdisk(md_list{i},[md_list{i}.name '.outbin']);
+
+	%post solve phase
+	md_list{i}=postsolveparallel(md_list{i});
+	delete([name '.outbin']);
+end
+
+%erase files 
+delete('ModelResults.tar.gz');
Index: /issm/trunk/src/m/model/loadresultsfromcluster.m
===================================================================
--- /issm/trunk/src/m/model/loadresultsfromcluster.m	(revision 5901)
+++ /issm/trunk/src/m/model/loadresultsfromcluster.m	(revision 5901)
@@ -0,0 +1,75 @@
+function md=loadresultsfromcluster(md,runtimename)
+%LOADRESULTSFROMCLUSTER - load results of solution sequence from cluster
+%
+%   Usage:
+%      md=loadresultsfromcluster(md,runtimename);
+
+%Get cluster.rc location
+cluster_rc_location=which('cluster.rc');
+
+%Figure out parameters for this particular cluster
+[codepath,executionpath,login,port]=ClusterParameters(md.cluster,cluster_rc_location);
+
+if nargin==2,
+	md.runtimename=runtimename;
+end
+
+if isempty(md.runtimename),
+	error('supply runtime name for results to be loaded!');
+end
+
+%Figure out the  directory where all the files are in: 
+directory=[executionpath '/' md.runtimename '/'];
+
+%What packages are we picking up from remote cluster
+packages={[md.name '.outlog'],[md.name '.errlog']};
+if md.qmu_analysis,
+	packages{end+1}=[md.name '.qmu.err'];
+	packages{end+1}=[md.name '.qmu.out'];
+	if isfield(md.qmu_params,'tabular_graphics_data'),
+		if md.qmu_params.tabular_graphics_data==true,
+			packages{end+1}='dakota_tabular.dat'; 
+		end
+	end
+else
+	packages{end+1}=[md.name '.outbin'];
+end
+
+%copy files from cluster to present directory
+issmscpin(md.cluster, login, port, directory, packages);
+
+%read log files onto  fields
+md.errlog=char(textread([md.name '.errlog'],'%s','delimiter','\n'));
+md.outlog=char(textread([md.name '.outlog'],'%s','delimiter','\n'));
+if ~isempty(md.errlog),
+	disp(['loadresultsfromcluster info message: error during solution. Check your errlog and outlog model fields']);
+end
+
+%If we are here, no errors in the solution sequence, call loadresultsfromdisk.
+md=loadresultsfromdisk(md,[md.name '.outbin']);
+
+%erase the log and output files
+if md.qmu_analysis,
+	delete([['qmu' num2str(GetPId) '/'] md.name '.outlog']);
+	delete([['qmu' num2str(GetPId) '/']  md.name '.errlog']);
+else
+	delete([md.name '.outlog']);
+	delete([md.name '.errlog']);
+	delete([md.name '.outbin']);
+	delete([md.runtimename '.tar.gz']);
+end
+
+%erase input file if run was carried out on same platform.
+hostname=oshostname();
+if strcmpi(hostname,md.cluster),
+	if md.qmu_analysis,
+		delete([['qmu' num2str(GetPId) '/'] md.name '.bin']);
+		delete([['qmu' num2str(GetPId) '/'] md.name '.queue']);
+	else
+		delete([md.name '.bin']);
+		delete([md.name '.queue']);
+	end
+end
+
+%post solve phase
+md=postsolveparallel(md);
Index: /issm/trunk/src/m/model/loadresultsfromdisk.m
===================================================================
--- /issm/trunk/src/m/model/loadresultsfromdisk.m	(revision 5901)
+++ /issm/trunk/src/m/model/loadresultsfromdisk.m	(revision 5901)
@@ -0,0 +1,49 @@
+function md=loadresultsfromdisk(md,filename)
+%LOADRESULTSFROMDISK - load results of solution sequence from disk file "filename"            
+%
+%   Usage:
+%      md=loadresultsfromdisk(md,filename);
+
+%check number of inputs/outputs
+if ((nargin~=2) | (nargout~=1)),
+	help loadresultsfromdisk;
+	error('loadresultsfromdisk: error message.');
+end
+
+if ~md.qmu_analysis,
+
+	%initialize md.results if not a structure yet
+	if ~isstruct(md.results),
+		md.results=struct();
+	end
+
+	%load results onto model
+	structure=parseresultsfromdisk(filename);
+	md.results.(structure.SolutionType)=structure;
+
+	%recover analysis_type from results
+	md.analysis_type=structure(1).SolutionType;
+	if isscalar(md.sub_analysis_type),
+		md.sub_analysis_type=EnumToString(md.sub_analysis_type);
+	end
+
+	%Check result is consistent, only if it exists
+	disp(sprintf('%s\n','checking result consistency'));
+	if ~isresultconsistent(md,structure(1).SolutionType),
+		%it would be very cruel to use an error, it would kill the computed results (although they are not consistent...)
+		disp('!! results not consistent correct the model !!') 
+	end
+
+%post processes qmu results if necessary
+else
+
+	if isscalar(md.analysis_type),
+		md.analysis_type    =EnumToString(md.analysis_type);
+	end
+	if isscalar(md.sub_analysis_type),
+		md.sub_analysis_type=EnumToString(md.sub_analysis_type);
+	end
+	md=postqmu(md);
+	cd ..
+
+end
Index: /issm/trunk/src/m/model/marshall.m
===================================================================
--- /issm/trunk/src/m/model/marshall.m	(revision 5901)
+++ /issm/trunk/src/m/model/marshall.m	(revision 5901)
@@ -0,0 +1,186 @@
+function marshall(md)
+%MARSHALL - output JPL-package compatible binary file from @model md, for certain solution type.
+%
+%   The routine creates a JPL-package compatible binary file from @model md
+%   This binary file will be used for parallel runs in JPL-package
+%
+%   Usage:
+%      marshall(md)
+
+%some checks on list of arguments
+if ((nargin~=3) & (nargout~=0))
+	help marshall;
+	error('marshall error message');
+end
+
+disp(['marshalling file ' md.name '.bin']);
+
+%open file for binary writing
+fid=fopen([ md.name '.bin'],'wb');
+if fid==-1,
+	error(['marshall error message: could not open ' [md.name '.bin'],' file for binary writing']);
+end
+
+WriteData(fid,md.analysis_type','Integer','analysis_type');
+WriteData(fid,md.sub_analysis_type','Integer','sub_analysis_type');
+WriteData(fid,md.dim,'Integer','dim');
+WriteData(fid,md.numberofgrids,'Integer','numberofgrids');
+WriteData(fid,md.numberofelements,'Integer','numberofelements');
+WriteData(fid,md.x,'Mat','x');
+WriteData(fid,md.y,'Mat','y');
+WriteData(fid,md.z,'Mat','z');
+WriteData(fid,md.elements,'Mat','elements');
+WriteData(fid,md.elements_type,'Mat','elements_type');
+WriteData(fid,md.vertices_type,'Mat','vertices_type');
+WriteData(fid,md.gridonhutter,'Mat','gridonhutter');
+WriteData(fid,md.gridonmacayeal,'Mat','gridonmacayeal');
+
+if md.dim==3,
+	WriteData(fid,md.numberofelements2d,'Integer','numberofelements2d');
+	WriteData(fid,md.numberofgrids2d,'Integer','numberofgrids2d');
+	WriteData(fid,md.elements2d,'Mat','elements2d');
+	WriteData(fid,md.numlayers,'Integer','numlayers');
+	WriteData(fid,md.gridonpattyn,'Mat','gridonpattyn');
+end
+WriteData(fid,md.upperelements,'Mat','upperelements');
+WriteData(fid,md.lowerelements,'Mat','lowerelements');
+WriteData(fid,md.elementonbed,'Mat','elementonbed');
+WriteData(fid,md.elementonsurface,'Mat','elementonsurface');
+WriteData(fid,md.gridonbed,'Mat','gridonbed');
+WriteData(fid,md.gridonsurface,'Mat','gridonsurface');
+WriteData(fid,md.gridonstokes,'Mat','gridonstokes');
+WriteData(fid,md.borderstokes,'Mat','borderstokes');
+
+
+WriteData(fid,md.thickness,'Mat','thickness');
+WriteData(fid,md.surface,'Mat','surface');
+WriteData(fid,md.bed,'Mat','bed');
+
+WriteData(fid,md.vx_obs,'Mat','vx_obs');
+WriteData(fid,md.vy_obs,'Mat','vy_obs');
+WriteData(fid,md.thickness_obs,'Mat','thickness_obs');
+
+WriteData(fid,md.vx,'Mat','vx');
+WriteData(fid,md.vy,'Mat','vy');
+WriteData(fid,md.vz,'Mat','vz');
+WriteData(fid,md.pressure,'Mat','pressure');
+WriteData(fid,md.temperature,'Mat','temperature');
+
+
+WriteData(fid,md.drag_type,'Integer','drag_type');
+WriteData(fid,md.drag_coefficient,'Mat','drag_coefficient');
+WriteData(fid,md.drag_p,'Mat','drag_p');
+WriteData(fid,md.drag_q,'Mat','drag_q');
+
+WriteData(fid,md.elementoniceshelf,'Mat','elementoniceshelf');
+WriteData(fid,md.elementonwater,'Mat','elementonwater');
+WriteData(fid,md.gridonicesheet,'Mat','gridonicesheet');
+WriteData(fid,md.gridoniceshelf,'Mat','gridoniceshelf');
+
+WriteData(fid,md.spcvelocity,'Mat','spcvelocity');
+WriteData(fid,md.spctemperature,'Mat','spctemperature');
+WriteData(fid,md.spcthickness,'Mat','spcthickness');
+
+WriteData(fid,md.pressureload,'Mat','pressureload');
+WriteData(fid,md.edges,'Mat','edges');
+
+WriteData(fid,md.geothermalflux,'Mat','geothermalflux');
+WriteData(fid,md.accumulation_rate,'Mat','accumulation_rate');
+WriteData(fid,md.melting_rate,'Mat','melting_rate');
+WriteData(fid,md.dhdt,'Mat','dhdt');
+
+%Get materials
+WriteData(fid,md.rho_water,'Scalar','rho_water');
+WriteData(fid,md.rho_ice,'Scalar','rho_ice');
+WriteData(fid,md.g,'Scalar','g');
+WriteData(fid,md.rheology_B,'Mat','rheology_B');
+WriteData(fid,md.rheology_n,'Mat','rheology_n');
+
+%Control methods
+WriteData(fid,md.control_analysis,'Integer','control_analysis');
+WriteData(fid,md.control_type,'Integer','control_type');
+
+%Write solution parameters
+WriteData(fid,md.cm_responses,'Mat','cm_responses');
+WriteData(fid,md.weights,'Mat','weights');
+WriteData(fid,md.cm_jump,'Mat','cm_jump');
+WriteData(fid,md.yts,'Scalar','yts');
+WriteData(fid,md.meanvel,'Scalar','meanvel');
+WriteData(fid,md.epsvel,'Scalar','epsvel');
+WriteData(fid,md.verbose,'Integer','verbose');
+WriteData(fid,md.plot,'Integer','plot');
+WriteData(fid,md.output_frequency,'Integer','output_frequency');
+WriteData(fid,md.artificial_diffusivity,'Integer','artificial_diffusivity');
+WriteData(fid,md.prognostic_DG,'Integer','prognostic_DG');
+WriteData(fid,md.nsteps,'Integer','nsteps');
+WriteData(fid,md.eps_cm,'Scalar','eps_cm');
+WriteData(fid,md.tolx,'Scalar','tolx');
+WriteData(fid,md.maxiter,'Mat','maxiter');
+WriteData(fid,md.cm_noisedmp,'Scalar','cm_noisedmp');
+WriteData(fid,md.cm_min,'Scalar','cm_min');
+WriteData(fid,md.cm_max,'Scalar','cm_max');
+WriteData(fid,md.cm_gradient,'Integer','cm_gradient');
+WriteData(fid,md.eps_res,'Scalar','eps_res');
+WriteData(fid,md.eps_rel,'Scalar','eps_rel');
+WriteData(fid,md.eps_abs,'Scalar','eps_abs');
+WriteData(fid,md.max_nonlinear_iterations,'Scalar','max_nonlinear_iterations');
+WriteData(fid,md.dt,'Scalar','dt');
+WriteData(fid,md.ndt,'Scalar','ndt');
+WriteData(fid,md.penalty_offset,'Scalar','penalty_offset');
+WriteData(fid,md.penalty_melting,'Scalar','penalty_melting');
+WriteData(fid,md.penalty_lock,'Integer','penalty_lock');
+WriteData(fid,md.sparsity,'Scalar','sparsity');
+WriteData(fid,md.connectivity,'Integer','connectivity');
+WriteData(fid,md.lowmem,'Integer','lowmem');
+WriteData(fid,md.optscal,'Mat','optscal');
+WriteData(fid,md.solverstring,'String','solverstring');
+WriteData(fid,md.viscosity_overshoot,'Scalar','viscosity_overshoot');
+WriteData(fid,md.stokesreconditioning,'Scalar','stokesreconditioning');
+WriteData(fid,md.waitonlock,'Scalar','waitonlock');
+WriteData(fid,md.kff,'Integer','kff');
+
+%Thermal parameters
+WriteData(fid,md.beta,'Scalar','beta');
+WriteData(fid,md.meltingpoint,'Scalar','meltingpoint');
+WriteData(fid,md.latentheat,'Scalar','latentheat');
+WriteData(fid,md.heatcapacity,'Scalar','heatcapacity');
+WriteData(fid,md.thermalconductivity,'Scalar','thermalconductivity');
+WriteData(fid,md.min_thermal_constraints,'Integer','min_thermal_constraints');
+WriteData(fid,md.min_mechanical_constraints,'Integer','min_mechanical_constraints');
+WriteData(fid,md.mixed_layer_capacity,'Scalar','mixed_layer_capacity');
+WriteData(fid,md.thermal_exchange_velocity,'Scalar','thermal_exchange_velocity');
+WriteData(fid,md.stabilize_constraints,'Integer','stabilize_constraints');
+
+%elements type
+WriteData(fid,md.ishutter,'Integer','ishutter');
+WriteData(fid,md.ismacayealpattyn,'Integer','ismacayealpattyn');
+WriteData(fid,md.isstokes,'Integer','isstokes');
+
+%Rifts
+WriteData(fid,md.riftinfo,'Mat','riftinfo');
+
+%parameter output.
+md.numoutput=length(md.parameteroutput);
+WriteData(fid,md.numoutput,'Integer','numoutput');
+if(md.numoutput),
+	for i=1:md.numoutput,
+		WriteData(fid,md.parameteroutput{i},'String',['parameteroutput_' num2str(i-1)]);
+	end
+end
+
+%Qmu: the rest will be handle by qmumarshall
+WriteData(fid,md.qmu_analysis,'Integer','qmu_analysis');
+WriteData(fid,md.name,'String','name');
+
+%Get penalties
+WriteData(fid,md.penalties,'Mat','penalties');
+
+%input and output file names
+WriteData(fid,md.inputfilename,'String','inputfilename');
+WriteData(fid,md.outputfilename,'String','outputfilename');
+
+%close file
+st=fclose(fid);
+if st==-1,
+	error(['marshall error message: could not close file ' [md.name '.bin']]);
+end
Index: /issm/trunk/src/m/model/mechanicalproperties.m
===================================================================
--- /issm/trunk/src/m/model/mechanicalproperties.m	(revision 5901)
+++ /issm/trunk/src/m/model/mechanicalproperties.m	(revision 5901)
@@ -0,0 +1,118 @@
+function md=mechanicalproperties(md,vx,vy)
+%MECHANICALPROPERTIES - compute stress and strain rate for a goven velocity
+%
+%   this routine computes the components of the stress tensor
+%   strain rate tensor and their respective principal directions.
+%   the results are in the model md: md.stress and md.strainrate
+%
+%   Usage:
+%      md=mechanicalproperties(md,vx,vy)
+%
+%   Example:
+%      md=mechanicalproperties(md,md.vx,md.vy);
+%      md=mechanicalproperties(md,md.vx_obs,md.vy_obs);
+
+%some checks
+if length(vx)~=md.numberofgrids | length(vy)~=md.numberofgrids,
+	error(['the input velocity should be of size ' num2str(md.numberofgrids) '!'])
+end
+if ~(md.dim==2)
+	error('only 2d model supported yet');
+end
+if any(md.elements_type~=MacAyealApproximationEnum),
+	disp('Warning: the model has some non macayeal elements. These will be treated like MacAyeal''s elements');
+end
+
+%initialization
+numberofelements=md.numberofelements;
+index=md.elements;
+summation=[1;1;1];
+directionsstress=zeros(numberofelements,4);
+directionsstrain=zeros(numberofelements,4);
+valuesstress=zeros(numberofelements,2);
+valuesstrain=zeros(numberofelements,2);
+
+%compute nodal functions coefficients N(x,y)=alpha x + beta y +gamma
+[alpha beta]=GetNodalFunctionsCoeff(index,md.x,md.y);
+
+%compute shear
+vxlist=vx(index)/md.yts;
+vylist=vy(index)/md.yts;
+ux=(vxlist.*alpha)*summation;
+uy=(vxlist.*beta)*summation;
+vx=(vylist.*alpha)*summation;
+vy=(vylist.*beta)*summation;						
+uyvx=(vx+uy)./2;
+clear vxlist vylist
+
+%compute viscosity
+nu=zeros(numberofelements,1);
+B_bar=md.B(index)*summation/3;
+power=(md.n-1)./(2*md.n);
+second_inv=(ux.^2+vy.^2+((uy+vx).^2)/4+ux.*vy);
+%some corrections
+location=find(second_inv~=0);
+nu(location)=B_bar(location)./(second_inv(location).^power(location));
+location=find(second_inv==0 & power~=0);
+nu(location)=10^18; 	%arbitrary maximum viscosity to apply where there is no effective shear
+location=find(second_inv==0 & power==0);
+nu(location)=B_bar(location);
+clear B_bar location second_inv power
+
+%compute stress
+tau_xx=nu.*ux;
+tau_yy=nu.*vy;
+tau_xy=nu.*uyvx;
+
+%compute principal properties of stress
+for i=1:numberofelements,
+
+	%compute stress and strainrate matrices
+	stress=[tau_xx(i) tau_xy(i)
+	tau_xy(i)  tau_yy(i)];
+	strain=[ux(i) uyvx(i)
+	uyvx(i)  vy(i)];
+
+	%eigen values and vectors
+	[directions,value]=eig(stress);
+	valuesstress(i,:)=[value(1,1) value(2,2)];
+	directionsstress(i,:)=directions(:)';
+	[directions,value]=eig(strain);
+	valuesstrain(i,:)=[value(1,1) value(2,2)];
+	directionsstrain(i,:)=directions(:)';
+end
+
+%plug onto the model
+%NB: Matlab sorts the eigen value in increasing order, we want the reverse
+stress=struct('xx',[],'yy',[],'xy',[],'principalvalue1',[],'principalaxis1',[],'principalvalue2',[],'principalaxis2',[],'effectivevalue',[]);
+stress.xx=tau_xx;
+stress.yy=tau_yy;
+stress.xy=tau_xy;
+stress.principalvalue2=valuesstress(:,1);
+stress.principalaxis2=directionsstress(:,1:2);
+stress.principalvalue1=valuesstress(:,2);
+stress.principalaxis1=directionsstress(:,3:4);
+stress.effectivevalue=1/sqrt(2)*sqrt(stress.xx.^2+stress.yy.^2+2*stress.xy.^2);
+md.stress=stress;
+
+strainrate=struct('xx',[],'yy',[],'xy',[],'principalvalue1',[],'principalaxis1',[],'principalvalue2',[],'principalaxis2',[],'effectivevalue',[]);
+strainrate.xx=ux;
+strainrate.yy=vy;
+strainrate.xy=uyvx;
+strainrate.principalvalue2=valuesstrain(:,1)*(365.25*24*3600); %strain rate in 1/a instead of 1/s
+strainrate.principalaxis2=directionsstrain(:,1:2);
+strainrate.principalvalue1=valuesstrain(:,2)*(365.25*24*3600); %strain rate in 1/a instead of 1/s
+strainrate.principalaxis1=directionsstrain(:,3:4);
+strainrate.effectivevalue=1/sqrt(2)*sqrt(strainrate.xx.^2+strainrate.yy.^2+2*strainrate.xy.^2);
+md.strainrate=strainrate;
+
+deviatoricstress=struct('xx',[],'yy',[],'xy',[],'principalvalue1',[],'principalaxis1',[],'principalvalue2',[],'principalaxis2',[],'effectivevalue',[]);
+deviatoricstress.xx=tau_xx;
+deviatoricstress.yy=tau_yy;
+deviatoricstress.xy=tau_xy;
+deviatoricstress.principalvalue2=valuesstress(:,1);
+deviatoricstress.principalaxis2=directionsstress(:,1:2);
+deviatoricstress.principalvalue1=valuesstress(:,2);
+deviatoricstress.principalaxis1=directionsstress(:,3:4);
+deviatoricstress.effectivevalue=1/sqrt(2)*sqrt(stress.xx.^2+stress.yy.^2+2*stress.xy.^2);
+md.deviatoricstress=deviatoricstress;
Index: /issm/trunk/src/m/model/mesh/findsegments.m
===================================================================
--- /issm/trunk/src/m/model/mesh/findsegments.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/findsegments.m	(revision 5901)
@@ -0,0 +1,92 @@
+function segments=findsegments(md,varargin)
+%FINDSEGMENTS - build segments model field
+%
+%   Optional inputs:
+%      'elementconnectivity'
+%
+%   Usage:
+%      segments=findsegments(md,varargin);
+
+%get options
+options=pairoptions(varargin{:});
+
+%Get connectivity
+elementconnectivity=getfieldvalue(options,'elementconnectivity',md.elementconnectivity);
+
+%Now, build the connectivity tables for this mesh if not correclty done
+if size(md.elementconnectivity,1)~=md.numberofelements,
+	if exist(options,'elementconnectivity'),
+		error(' ''elementconnectivity'' option does not have thge right size.');
+	else
+		elementconnectivity=ElementConnectivity(md.elements,md.nodeconnectivity);
+	end
+end
+
+%Recreate the segments
+elementonboundary=double(elementconnectivity(:,3)==0);
+pos=find(elementonboundary);
+num_segments=length(pos);
+segments=zeros(num_segments,3);
+count=1;
+
+%loop over the segments
+for i=1:num_segments,
+
+	%get current element on boundary
+	el1=pos(i);
+
+	%get elements connected to el1
+	els2=elementconnectivity(el1,find(elementconnectivity(el1,:)));
+
+	%el1 is connected to 2 other elements
+	if length(els2)>1,
+
+		%get nodes of el1
+		nods1=md.elements(el1,:);
+
+		%find the common vertices to the two elements connected to el1 (1 or 2)
+		flag=intersect(md.elements(els2(1),:),md.elements(els2(2),:));
+
+		%get the vertices on the boundary and build segment
+		nods1(find(ismember(nods1,flag)))=[];
+		segments(count,:)=[nods1 el1];
+
+		%swap segment grids if necessary
+		ord1=find(nods1(1)==md.elements(el1,:));
+		ord2=find(nods1(2)==md.elements(el1,:));
+		if ( (ord1==1 & ord2==2) | (ord1==2 & ord2==3) | (ord1==3 & ord2==1) ),
+			temp=segments(count,1);
+			segments(count,1)=segments(count,2);
+			segments(count,2)=temp;
+		end
+		segments(count,1:2)=fliplr(segments(count,1:2));
+		count=count+1;
+
+	%el1 is connected to only one element
+	else
+		%get nodes of el1
+		nods1=md.elements(el1,:);
+
+		%find the vertex  the el1 to not share with els2
+		flag=setdiff(nods1,md.elements(els2,:));
+
+		for j=1:3,
+			nods=nods1; nods(j)=[];
+			if any(ismember(flag,nods)),
+
+				segments(count,:)=[nods el1];
+
+				%swap segment grids if necessary
+				ord1=find(nods(1)==md.elements(el1,:));
+				ord2=find(nods(2)==md.elements(el1,:));
+				if ( (ord1==1 & ord2==2) | (ord1==2 & ord2==3) | (ord1==3 & ord2==1) ),
+					temp=segments(count,1);
+					segments(count,1)=segments(count,2);
+					segments(count,2)=temp;
+				end
+				segments(count,1:2)=fliplr(segments(count,1:2));
+				count=count+1;
+			end
+		end
+	end
+end
Index: /issm/trunk/src/m/model/mesh/mesh.m
===================================================================
--- /issm/trunk/src/m/model/mesh/mesh.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/mesh.m	(revision 5901)
@@ -0,0 +1,96 @@
+function md=mesh(md,domainname,varargin)
+%MESH - create model mesh
+%
+%   This routine creates a model mesh using TriMesh and a domain outline, to within a certain resolution
+%   where md is a @model object, domainname is the name of an Argus domain outline file, 
+%   and resolution is a characteristic length for the mesh (same unit as the domain outline
+%   unit). Riftname is an optional argument (Argus domain outline) describing rifts.
+%
+%   Usage:
+%      md=mesh(md,domainname,resolution)
+%   or md=mesh(md,domainname,riftname, resolution)
+%
+%   Examples:
+%      md=mesh(md,'DomainOutline.exp',1000);
+%      md=mesh(md,'DomainOutline.exp','Rifts.exp',1500);
+
+%Figure out a characteristic area. Resolution is a grid oriented concept (ex a 1000m  resolution grid would 
+%be made of 1000*1000 area squares). 
+if (nargin==3),
+	resolution=varargin{1};
+	riftname='';
+end
+if (nargin==4),
+	riftname=varargin{1};
+	resolution=varargin{2};
+end
+
+%Check that mesh was not already run, and warn user: 
+if subsref(md,struct('type','.','subs','counter'))>=1,
+	choice=input('This model already has a mesh. Are you sure you want to go ahead? (y/n)','s');
+	if ~strcmp(choice,'y')
+		disp('no meshing done ... exiting');
+		return
+	end
+end
+
+area=resolution^2;
+
+%Mesh using TriMesh
+if strcmp(riftname,''),
+	[md.elements,md.x,md.y,md.segments,md.segmentmarkers]=TriMesh(domainname,area,'yes');
+else
+	[elements,x,y,segments,segmentmarkers]=TriMesh(domainname,riftname,area,'yes');
+
+	%check that all the created grids belong to at least one element
+	orphan=find(~ismember([1:length(x)],sort(unique(elements(:)))));
+	for i=1:length(orphan),
+		%get rid of the orphan grid i
+		%update x and y
+		x=[x(1:orphan(i)-(i-1)-1); x(orphan(i)-(i-1)+1:end)];
+		y=[y(1:orphan(i)-(i-1)-1); y(orphan(i)-(i-1)+1:end)];
+		%update elements
+		pos=find(elements>orphan(i)-(i-1));
+		elements(pos)=elements(pos)-1;
+		%update segments
+		pos1=find(segments(:,1)>orphan(i)-(i-1));
+		pos2=find(segments(:,2)>orphan(i)-(i-1));
+		segments(pos1,1)=segments(pos1,1)-1;
+		segments(pos2,2)=segments(pos2,2)-1;
+	end
+
+	%plug into md
+	md.x=x;
+	md.y=y;
+	md.elements=elements;
+	md.segments=segments;
+	md.segmentmarkers=segmentmarkers;
+end
+
+%Fill in rest of fields:
+md.numberofelements=length(md.elements);
+md.numberofgrids=length(md.x);
+md.z=zeros(md.numberofgrids,1);
+md.gridonboundary=zeros(md.numberofgrids,1); md.gridonboundary(md.segments(:,1:2))=1;
+md.gridonbed=ones(md.numberofgrids,1);
+md.gridonsurface=ones(md.numberofgrids,1);
+md.elementonbed=ones(md.numberofelements,1);
+md.elementonsurface=ones(md.numberofelements,1);
+
+%Now, build the connectivity tables for this mesh.
+md.nodeconnectivity=NodeConnectivity(md.elements,md.numberofgrids);
+md.elementconnectivity=ElementConnectivity(md.elements,md.nodeconnectivity);
+
+%outline names
+md.domainoutline=char(textread(domainname,'%s','delimiter','\n'));
+if strcmp(riftname,''),
+	md.riftoutline='';
+else
+	md.riftoutline=readfile(riftname);
+end
+
+%type of model
+md.dim=2;
+	
+%augment counter  keeping track of what has been done to this model
+md.counter=1;
Index: /issm/trunk/src/m/model/mesh/meshadaptation.m
===================================================================
--- /issm/trunk/src/m/model/mesh/meshadaptation.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/meshadaptation.m	(revision 5901)
@@ -0,0 +1,94 @@
+function md2=meshadaptation(md,field,scale,epsilon,threshold)
+%MESHADAPTATION - remesh a model for a given field
+%
+%   remesh a model for a given field, use the hessian computation to spread the error on the element
+%   scale: 1.2 large scale leads to higher refining.
+%   epsilon: .5  large epsilon will refine fewer elements
+%   threshold: value under which no refinement is done.
+%
+%   Usage:
+%      md2=meshadaptation(md,field,scale,epsilon,threshold)
+%
+%   Example:
+%      md2=meshadaptation(md,md.vel,1.2,0.5,1);
+
+%some checks
+if ~(md.dim==2)
+	error('meshadaptation error message: adaptation for 3d meshes not implemented yet')
+end
+if length(field)~=md.numberofgrids
+	error('meshadaptation error message: input field length shoud be numberofgrids')
+end
+
+disp(sprintf('      metric computation') )
+
+%initialization
+index=md.elements;
+numberofgrids=md.numberofgrids;
+numberofelements=md.numberofelements;
+gradx=zeros(numberofgrids,1);
+grady=zeros(numberofgrids,1);
+metric=zeros(numberofelements,1);
+
+%take the threshold, a characteristic length, and get the area equivalent threshold:
+threshold=threshold^2/2;
+
+%build some usefull variables
+field=field(:);
+line=index(:);
+summation=1/3*ones(3,1);
+linesize=3*numberofelements;
+
+%get areas and  nodal functions coefficients N(x,y)=alpha x + beta y + gamma 
+[alpha beta]=GetNodalFunctionsCoeff(index,md.x,md.y);
+areas=GetAreas(index,md.x,md.y);
+
+%Compute gradient for each element
+grad_elx=sum(field(index).*alpha,2); 
+grad_ely=sum(field(index).*beta,2);
+
+%update weights that holds the volume of all the element holding the grid i
+weights=sparse(line,ones(linesize,1),repmat(areas,3,1),numberofgrids,1);
+
+%Compute gradient for each grid (average of the elements around)
+gradx=sparse(line,ones(linesize,1),repmat(areas.*grad_elx,3,1),numberofgrids,1);
+grady=sparse(line,ones(linesize,1),repmat(areas.*grad_ely,3,1),numberofgrids,1);
+gradx=gradx./weights;
+grady=grady./weights;
+
+%Compute hessian for each element
+hessian=[sum(gradx(index).*alpha,2) sum(grady(index).*beta,2) sum(grady(index).*alpha,2)];
+
+%Compute the new metric
+hmin=min(sqrt(areas))/scale;
+hmax=max(sqrt(areas));
+
+%first, find the eigen values of eah line of H=[hessian(i,1) hessian(i,3); hessian(i,3)  hessian(i,2)]
+a=hessian(:,1); b=hessian(:,3); d=hessian(:,2);
+lambda1=0.5*((a+d)+sqrt(4*b.^2+(a-d).^2));
+lambda2=0.5*((a+d)-sqrt(4*b.^2+(a-d).^2));
+
+%Modify the eigen values to control the shape of the elements
+lambda1=min(max(abs(lambda1)/epsilon,1/hmax^2),1/hmin^2);
+lambda2=min(max(abs(lambda2)/epsilon,1/hmax^2),1/hmin^2);
+
+%find the corresponding eigen vectors of the initial eigen values
+%NOT USED FOR NOW
+%div1=sqrt(1+(b./(lambda1-d)).^2);
+%div2=sqrt(1+(b./(lambda2-d)).^2);
+%vector1=[1./div1 (b./(lambda1-d))./div1];
+%vector2=[1./div2 (b./(lambda2-d))./div2];
+
+%compute the metric
+%R=[vector1(:,1) vector2(:,1) vector1(:,2) vector2(:,2)];
+%det=vector1(:,1).*vector2(:,2)-vector1(:,2).*vector1(:,2);
+%Rinv=[vector2(:,2)./det   -vector2(:,1)./det   -vector1(:,2)./det   vector1(:,1)./det];
+metric=20*1./sqrt(lambda1.^2+lambda2.^2);
+
+%ok, metric can't go under 1km resolution.
+metric(find(metric<threshold))=threshold;
+
+%Remesh with this new metric
+disp(sprintf('      initial number of element: %i', md.numberofelements))
+md2=meshrefine(md,full(metric));
+disp(sprintf('      new number of elements:    %i', md2.numberofelements))
Index: /issm/trunk/src/m/model/mesh/meshbamg.m
===================================================================
--- /issm/trunk/src/m/model/mesh/meshbamg.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/meshbamg.m	(revision 5901)
@@ -0,0 +1,112 @@
+function md=meshbamg(md,varargin);
+%MESHYAMS - Build model of Antarctica by refining according to observed velocity error estimator
+%
+%   Usage:
+%      md=meshyams(md,varargin);
+%      where varargin is a lit of paired arguments. 
+%      arguments can be: 'domainoutline': Argus file containing the outline of the domain to be meshed
+%      arguments can be: 'domainoutline': Argus file containing the outline of the domain to be meshed
+%      arguments can be: 'thickness': matlab file containing the thickness [m]
+%      optional arguments: 'groundeddomain': Argus file containing the outline of the grounded ice
+%                          this option is used to minimize the metric on water (no refinement)
+%      optional arguments: 'resolution': initial mesh resolution [m]
+%      optional arguments: 'nsteps': number of steps of mesh adaptation
+%      optional arguments: 'epsilon': average interpolation error wished [m/yr [m]]
+%      optional arguments: 'hmin': minimum edge length
+%      optional arguments: 'hmanx': maximum edge
+%      
+%
+%   Examples:
+%      md=meshyams(md,'domainoutline','Domain.exp','velocities','vel.mat');
+%      md=meshyams(md,'domainoutline','Domain.exp','velocities','vel.mat','groundeddomain','ground.exp');
+%      md=meshyams(md,'domainoutline','Domain.exp','velocities','vel.mat','groundeddomain','ground.exp','nsteps',6,'epsilon',2,'hmin',500,'hmax',30000);
+%      md=meshyams(md,'domainoutline','Domain.exp','velocities','vel.mat','thickness','groundeddomain','ground.exp','nsteps',6,'epsilon',2,'hmin',500,'hmax',30000);
+
+%recover options
+options=pairoptions(varargin{:});
+options=deleteduplicates(options,1);
+
+%recover some fields
+disp('MeshBamg Options:')
+domainoutline=getfieldvalue(options,'domainoutline');
+disp(sprintf('   %-15s: ''%s''','DomainOutline',domainoutline));
+groundeddomain=getfieldvalue(options,'groundeddomain','N/A');
+disp(sprintf('   %-15s: ''%s''','GroundedDomain',groundeddomain));
+velocities=getfieldvalue(options,'velocities');
+disp(sprintf('   %-15s: ''%s''','Velocities',velocities));
+thickness=getfieldvalue(options,'thickness','none');
+disp(sprintf('   %-15s: ''%s''','Thickness',thickness));
+resolution=getfieldvalue(options,'resolution',5000);
+disp(sprintf('   %-15s: %f','Resolution',resolution));
+nsteps=getfieldvalue(options,'nsteps',6);
+disp(sprintf('   %-15s: %i','nsteps',nsteps));
+gradation=getfieldvalue(options,'gradation',2*ones(nsteps,1));
+disp(sprintf('   %-15s: %g','gradation',gradation(1)));
+epsilon=getfieldvalue(options,'epsilon',3);
+disp(sprintf('   %-15s: %f','epsilon',epsilon));
+hmin=getfieldvalue(options,'hmin',500);
+disp(sprintf('   %-15s: %f','hmin',hmin));
+hmax=getfieldvalue(options,'hmax',150*10^3);
+disp(sprintf('   %-15s: %f\n','hmax',hmax));
+
+%mesh with initial resolution
+disp('Initial mesh generation...');
+md=mesh(md,domainoutline,resolution);
+disp(['Initial mesh, number of elements: ' num2str(md.numberofelements)]);
+
+%load velocities 
+disp('loading velocities...');
+NamesV=VelFindVarNames(velocities);
+Vel=load(velocities);
+
+%compute thickness?
+if ~strcmpi(thickness,'none'),
+	disp('loading thickness...');
+	NamesH=FieldFindVarNames(thickness);
+	Thi=load(thickness);
+	thicknesspresent=1;
+else
+	thicknesspresent=0;
+end
+
+%start mesh adaptation
+for i=1:nsteps,
+	disp(['Iteration #' num2str(i) '/' num2str(nsteps)]);
+
+	%interpolate velocities onto mesh
+	disp('   interpolating velocities...');
+	if strcmpi(NamesV.interp,'grid'),
+		vx_obs=InterpFromGridToMesh(Vel.(NamesV.xname),Vel.(NamesV.yname),Vel.(NamesV.vxname),md.x,md.y,0);
+		vy_obs=InterpFromGridToMesh(Vel.(NamesV.xname),Vel.(NamesV.yname),Vel.(NamesV.vyname),md.x,md.y,0);
+	else
+		vx_obs=InterpFromMeshToMesh2d(Vel.(NamesV.indexname),Vel.(NamesV.xname),Vel.(NamesV.yname),Vel.(NamesV.vxname),md.x,md.y,0);
+		vy_obs=InterpFromMeshToMesh2d(Vel.(NamesV.indexname),Vel.(NamesV.xname),Vel.(NamesV.yname),Vel.(NamesV.vyname),md.x,md.y,0);
+	end
+	field=sqrt(vx_obs.^2+vy_obs.^2);
+	
+	if thicknesspresent,
+		disp('   interpolating thickness...');
+		if strcmpi(NamesH.interp,'grid'),
+			h=InterpFromGridToMesh(Thi.(NamesH.xname),Thi.(NamesH.yname),Thi.(NamesH.dataname),md.x,md.y,0);
+		else
+			h=InterpFromMeshToMesh2d(Thi.(NamesH.indexname),Thi.(NamesH.xname),Thi.(NamesH.yname),Thi.(NamesH.dataname),md.x,md.y,0);
+		end
+		field=[field h];
+	end
+	
+	%set gridonwater field
+	if ~strcmp(groundeddomain,'N/A'),
+		gridground=ContourToMesh(md.elements,md.x,md.y,groundeddomain,'node',2);
+		md.gridonwater=ones(md.numberofgrids,1);
+		md.gridonwater(find(gridground))=0;
+	else
+		md.gridonwater=zeros(md.numberofgrids,1);
+	end
+
+	%adapt according to velocities
+	disp('   adapting...');
+	md=bamg(md,'field',field,'hmin',hmin,'hmax',hmax,'gradation',gradation(i),'err',epsilon);
+
+end
+	
+disp(['Final mesh, number of elements: ' num2str(md.numberofelements)]);
Index: /issm/trunk/src/m/model/mesh/meshconvert.m
===================================================================
--- /issm/trunk/src/m/model/mesh/meshconvert.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/meshconvert.m	(revision 5901)
@@ -0,0 +1,48 @@
+function md=meshconvert(md,varargin)
+%CONVERTMESH - convert mesh to bamg mesh
+%
+%   Usage:
+%      md=meshconvert(md);
+%      md=meshconvert(md,index,x,y);
+
+if nargin~=1 & nargin~=4,
+	help meshconvert
+	error('meshconvert error message: bad usage');
+end
+
+if nargin==1,
+	x=md.x;
+	y=md.y;
+	index=md.elements;
+else
+	x=varargin{1};
+	y=varargin{2};
+	index=varargin{3};
+end
+
+%call Bamg
+[bamgmesh_out bamggeom_out]=BamgConvertMesh(index,x,y);
+
+% plug results onto model
+md.bamg=struct();
+md.bamg.mesh=bamgmesh(bamgmesh_out);
+md.bamg.geometry=bamggeom(bamggeom_out);
+md.x=bamgmesh_out.Vertices(:,1);
+md.y=bamgmesh_out.Vertices(:,2);
+md.elements=bamgmesh_out.Triangles(:,1:3);
+md.edges=bamgmesh_out.IssmEdges;
+md.segments=bamgmesh_out.IssmSegments(:,1:3);
+md.segmentmarkers=bamgmesh_out.IssmSegments(:,4);
+
+%Fill in rest of fields:
+md.dim=2;
+md.numberofelements=size(md.elements,1);
+md.numberofgrids=length(md.x);
+md.z=zeros(md.numberofgrids,1);
+md.gridonbed=ones(md.numberofgrids,1);
+md.gridonwater=zeros(md.numberofgrids,1);
+md.gridonsurface=ones(md.numberofgrids,1);
+md.elementonbed=ones(md.numberofelements,1);
+md.elementonsurface=ones(md.numberofelements,1);
+md.gridonboundary=zeros(md.numberofgrids,1); md.gridonboundary(md.segments(:,1:2))=1;
+md.counter=1;
Index: /issm/trunk/src/m/model/mesh/meshexprefine.m
===================================================================
--- /issm/trunk/src/m/model/mesh/meshexprefine.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/meshexprefine.m	(revision 5901)
@@ -0,0 +1,59 @@
+function md=meshexprefine(md,domainname,newresolution)
+%MESHEXPREFINE - refine mesh from a model
+%
+%   This routine refines a mesh for a given area using an Argus domain outline 
+%   and a new resolution for this domain.
+%   Appending ~ at the beginning of domainname will make this routine refine
+%   the elements which are not in the domain outline. 
+%   newresolution is the resolution to which the flagged elements must be refined.
+%
+%   Usage:
+%      md=meshexprefine(md,domainname,newresolution)
+%
+%   Example:
+%      md=meshexprefine(md,'RefineAreas.exp',1000)
+
+%some checks on list of arguments
+if ((nargin~=3) | (nargout~=1)),
+	meshexprefineusage();
+	error('meshexprefine error message');
+end
+
+if ~ischar(domainname) 
+	meshexprefineusage();
+	error('meshexprefine error message');
+end
+
+if (md.counter<1)
+	error('meshexprefine error message: you need to run mesh.m first on this model');
+end
+
+%Check the first letter of domainname, if it is ~, then we need to strip it away from 
+%domainname. The subsequent refinement will be done on the mask of the domain outline.
+if strcmpi(domainname(1),'~'),
+	mask=1;
+	domainname=domainname(2:length(domainname));
+else
+	mask=0;
+end
+
+%Read domainame file into a matlab array (x,y):
+refinearea=ContourToMesh(md.elements,md.x,md.y,domainname,'element',1);
+aires=GetAreas(md.elements,md.x,md.y);
+
+%flags areas within the domain
+if mask==1,
+	pos=find(~refinearea);
+else
+	pos=find(refinearea);
+end
+aires(pos)=newresolution*newresolution/2; %triangle area
+
+pos=find(refinearea);
+aires(pos)=2*aires(pos); %be sure this does not get refined.
+
+%refine using the new area vector
+md=meshrefine(md,aires);
+
+%return model
+end
Index: /issm/trunk/src/m/model/mesh/meshnodensity.m
===================================================================
--- /issm/trunk/src/m/model/mesh/meshnodensity.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/meshnodensity.m	(revision 5901)
@@ -0,0 +1,82 @@
+function md=meshnodensity(md,domainname,varargin)
+%MESH - create model mesh
+%
+%   This routine creates a model mesh using TriMeshNoDensity and a domain outline
+%   where md is a @model object, domainname is the name of an Argus domain outline file, 
+%   Riftname is an optional argument (Argus domain outline) describing rifts.
+%   The  difference with mesh.m is that the resolution of the mesh follows that of the domain 
+%   outline and the riftoutline
+%
+%   Usage:
+%      md=mesh(md,domainname)
+%   or md=mesh(md,domainname,riftname);
+%
+%   Examples:
+%      md=mesh(md,'DomainOutline.exp');
+%      md=mesh(md,'DomainOutline.exp','Rifts.exp');
+
+if (nargin==2),
+	riftname='';
+end
+if (nargin==3),
+	riftname=varargin{1};
+end
+
+%Mesh using TriMeshNoDensity
+if strcmp(riftname,''),
+	[md.elements,md.x,md.y,md.segments,md.segmentmarkers]=TriMeshNoDensity(domainname);
+else
+	[elements,x,y,segments,segmentmarkers]=TriMeshNoDensity(domainname,riftname);
+
+	%check that all the created grids belong to at least one element
+	orphan=find(~ismember([1:length(x)],sort(unique(elements(:)))));
+	for i=1:length(orphan),
+		%get rid of the orphan grid i
+		%update x and y
+		x=[x(1:orphan(i)-(i-1)-1); x(orphan(i)-(i-1)+1:end)];
+		y=[y(1:orphan(i)-(i-1)-1); y(orphan(i)-(i-1)+1:end)];
+		%update elements
+		pos=find(elements>orphan(i)-(i-1));
+		elements(pos)=elements(pos)-1;
+		%update segments
+		pos1=find(segments(:,1)>orphan(i)-(i-1));
+		pos2=find(segments(:,2)>orphan(i)-(i-1));
+		segments(pos1,1)=segments(pos1,1)-1;
+		segments(pos2,2)=segments(pos2,2)-1;
+	end
+
+	%plug into md
+	md.x=x;
+	md.y=y;
+	md.elements=elements;
+	md.segments=segments;
+	md.segmentmarkers=segmentmarkers;
+end
+
+%Fill in rest of fields:
+md.numberofelements=length(md.elements);
+md.numberofgrids=length(md.x);
+md.z=zeros(md.numberofgrids,1);
+md.gridonboundary=zeros(md.numberofgrids,1); md.gridonboundary(md.segments(:,1:2))=1;
+md.gridonbed=ones(md.numberofgrids,1);
+md.gridonsurface=ones(md.numberofgrids,1);
+md.elementonbed=ones(md.numberofelements,1);
+md.elementonsurface=ones(md.numberofelements,1);
+
+%Now, build the connectivity tables for this mesh.
+md.nodeconnectivity=NodeConnectivity(md.elements,md.numberofgrids);
+md.elementconnectivity=ElementConnectivity(md.elements,md.nodeconnectivity);
+
+%outline names
+md.domainoutline=char(textread(domainname,'%s','delimiter','\n'));
+if strcmp(riftname,''),
+	md.riftoutline='';
+else
+	md.riftoutline=readfile(riftname);
+end
+
+%type of model
+md.dim=2;
+	
+%augment counter  keeping track of what has been done to this model
+md.counter=1;
Index: /issm/trunk/src/m/model/mesh/meshrefine.m
===================================================================
--- /issm/trunk/src/m/model/mesh/meshrefine.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/meshrefine.m	(revision 5901)
@@ -0,0 +1,44 @@
+function md=meshrefine(md,areas)
+%MESHREFINE:  refined the mesh from a model, according to an area metric.
+%
+%   Usage:
+%      md=meshrefine(md,metric)
+
+%some checks on list of arguments
+if ((nargin~=2) | (nargout~=1)),
+	meshrefineusage();
+	error('meshrefine error message');
+end
+if ( (isempty(areas)) |  (length(areas)~=md.numberofelements) | (length(find(isnan(areas))))),
+	meshrefineusage();
+	error('meshrefine error message');
+end
+
+%Refine using TriMeshRefine
+%[md.elements,md.x,md.y,md.segments,md.rifts]=TriMeshRefine(md.elements,md.x,md.y,md.segments,md.rifts,areas,'yes');
+[md.elements,md.x,md.y,md.segments,md.segmentmarkers]=TriMeshRefine(md.elements,md.x,md.y,md.segments,md.segmentmarkers,areas,'yes');
+
+%Fill in rest of fields:
+md.numberofelements=length(md.elements);
+md.numberofgrids=length(md.x);
+md.z=zeros(md.numberofgrids,1);
+md.gridonboundary=zeros(md.numberofgrids,1); md.gridonboundary(md.segments(:,1:2))=1;
+md.gridonbed=ones(md.numberofgrids,1);
+md.gridonsurface=ones(md.numberofgrids,1);
+md.elementonbed=ones(md.numberofelements,1);
+md.elementonsurface=ones(md.numberofelements,1);
+
+%Now, build the connectivity tables for this mesh.
+md.nodeconnectivity=NodeConnectivity(md.elements,md.numberofgrids);
+md.elementconnectivity=ElementConnectivity(md.elements,md.nodeconnectivity);
+
+%type of model
+md.dim=2;
+	
+%augment counter  keeping track of what has been done to this model
+md.counter=1;
+end
+
+function meshrefineusage(),
+disp('usage: md=meshrefine(md,areas)');
+end
Index: /issm/trunk/src/m/model/mesh/meshyams.m
===================================================================
--- /issm/trunk/src/m/model/mesh/meshyams.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/meshyams.m	(revision 5901)
@@ -0,0 +1,172 @@
+function md=meshyams(md,varargin);
+%MESHYAMS - Build model of Antarctica by refining according to observed velocity error estimator
+%
+%   Usage:
+%      md=meshyams(md,varargin);
+%      where varargin is a lit of paired arguments. 
+%      arguments can be: 'domainoutline': Argus file containing the outline of the domain to be meshed
+%      arguments can be: 'velocities': matlab file containing the velocities [m/yr]
+%      optional arguments: 'groundeddomain': Argus file containing the outline of the grounded ice
+%                          this option is used to minimize the metric on water (no refinement)
+%      optional arguments: 'resolution': initial mesh resolution [m]
+%      optional arguments: 'nsteps': number of steps of mesh adaptation
+%      optional arguments: 'epsilon': average interpolation error wished [m/yr]
+%      optional arguments: 'hmin': minimum edge length
+%      optional arguments: 'hmanx': maximum edge
+%      optional arguments: 'riftoutline': if rifts are present, specifies rift outline file.
+%      
+%
+%   Examples:
+%      md=meshyams(md,'domainoutline','Domain.exp','velocities','vel.mat');
+%      md=meshyams(md,'domainoutline','Domain.exp','velocities','vel.mat','groundeddomain','ground.exp');
+%      md=meshyams(md,'domainoutline','Domain.exp','velocities','vel.mat','groundeddomain','ground.exp','nsteps',6,'epsilon',2,'hmin',500,'hmax',30000);
+
+%recover options
+options=pairoptions(varargin{:});
+options=deleteduplicates(options,1);
+
+%recover some fields
+disp('MeshYams Options:')
+domainoutline=getfieldvalue(options,'domainoutline');
+disp(sprintf('   %-15s: ''%s''','DomainOutline',domainoutline));
+riftoutline=getfieldvalue(options,'riftoutline','N/A');
+disp(sprintf('   %-15s: ''%s''','riftoutline',riftoutline));
+groundeddomain=getfieldvalue(options,'groundeddomain','N/A');
+disp(sprintf('   %-15s: ''%s''','GroundedDomain',groundeddomain));
+velocities=getfieldvalue(options,'velocities');
+disp(sprintf('   %-15s: ''%s''','Velocities',velocities));
+resolution=getfieldvalue(options,'resolution',5000);
+disp(sprintf('   %-15s: %f','Resolution',resolution));
+nsteps=getfieldvalue(options,'nsteps',6);
+disp(sprintf('   %-15s: %i','nsteps',nsteps));
+gradation=getfieldvalue(options,'gradation',2*ones(nsteps,1));
+disp(sprintf('   %-15s: %g','gradation',gradation(1)));
+epsilon=getfieldvalue(options,'epsilon',3);
+disp(sprintf('   %-15s: %f','epsilon',epsilon));
+hmin=getfieldvalue(options,'hmin',500);
+disp(sprintf('   %-15s: %f','hmin',hmin));
+hmax=getfieldvalue(options,'hmax',150*10^3);
+disp(sprintf('   %-15s: %f\n','hmax',hmax));
+
+%mesh with initial resolution
+disp('Initial mesh generation...');
+if strcmpi(riftoutline,'N/A');
+	md=mesh(md,domainoutline,resolution);
+else
+	md=mesh(md,domainoutline,riftoutline,resolution);
+	md=meshprocessrifts(md,domainoutline);
+end
+disp(['Initial mesh, number of elements: ' num2str(md.numberofelements)]);
+
+%load velocities 
+disp('loading velocities...');
+Names=VelFindVarNames(velocities);
+Vel=load(velocities);
+
+%start mesh adaptation
+for i=1:nsteps,
+	disp(['Iteration #' num2str(i) '/' num2str(nsteps)]);
+
+	%interpolate velocities onto mesh
+	disp('   interpolating velocities...');
+	if strcmpi(Names.interp,'grid'),
+		vx_obs=InterpFromGridToMesh(Vel.(Names.xname),Vel.(Names.yname),Vel.(Names.vxname),md.x,md.y,0);
+		vy_obs=InterpFromGridToMesh(Vel.(Names.xname),Vel.(Names.yname),Vel.(Names.vyname),md.x,md.y,0);
+	else
+		vx_obs=InterpFromMeshToMesh2d(Vel.(Names.indexname),Vel.(Names.xname),Vel.(Names.yname),Vel.(Names.vxname),md.x,md.y,0);
+		vy_obs=InterpFromMeshToMesh2d(Vel.(Names.indexname),Vel.(Names.xname),Vel.(Names.yname),Vel.(Names.vyname),md.x,md.y,0);
+	end
+	field=sqrt(vx_obs.^2+vy_obs.^2);
+
+	%set gridonwater field
+	if ~strcmp(groundeddomain,'N/A'),
+		gridground=ContourToMesh(md.elements,md.x,md.y,groundeddomain,'node',2);
+		md.gridonwater=ones(md.numberofgrids,1);
+		md.gridonwater(find(gridground))=0;
+	else
+		md.gridonwater=zeros(md.numberofgrids,1);
+	end
+
+	%adapt according to velocities
+	disp('   adapting...');
+	md=YamsCall(md,field,hmin,hmax,gradation(i),epsilon);
+
+	%if we have rifts, we just messed them up, we need to recreate the segments that constitute those 
+	%rifts, because the segments are used in YamsCall to freeze the rifts elements during refinement.
+	if md.numrifts, 
+		md.nodeconnectivity=NodeConnectivity(md.elements,md.numberofgrids);
+		md.elementconnectivity=ElementConnectivity(md.elements,md.nodeconnectivity);
+		md.segments=findsegments(md);
+		md=meshyamsrecreateriftsegments(md);
+	end
+
+end
+	
+disp(['Final mesh, number of elements: ' num2str(md.numberofelements)]);
+
+%Now, build the connectivity tables for this mesh.
+md.nodeconnectivity=NodeConnectivity(md.elements,md.numberofgrids);
+md.elementconnectivity=ElementConnectivity(md.elements,md.nodeconnectivity);
+
+%recreate segments
+md.segments=findsegments(md);
+md.gridonboundary=zeros(md.numberofgrids,1); md.gridonboundary(md.segments(:,1:2))=1;
+
+%Fill in rest of fields:
+md.z=zeros(md.numberofgrids,1);
+md.gridonbed=ones(md.numberofgrids,1);
+md.gridonsurface=ones(md.numberofgrids,1);
+md.elementonbed=ones(md.numberofelements,1);
+md.elementonsurface=ones(md.numberofelements,1);
+if ~strcmp(groundeddomain,'N/A'),
+	gridground=ContourToMesh(md.elements,md.x,md.y,groundeddomain,'node',2);
+	md.gridonwater=ones(md.numberofgrids,1);
+	md.gridonwater(find(gridground))=0;
+else
+	md.gridonwater=zeros(md.numberofgrids,1);
+end
+if strcmpi(Names.interp,'grid'),
+	md.vx_obs=InterpFromGridToMesh(Vel.(Names.xname),Vel.(Names.yname),Vel.(Names.vxname),md.x,md.y,0);
+	md.vy_obs=InterpFromGridToMesh(Vel.(Names.xname),Vel.(Names.yname),Vel.(Names.vyname),md.x,md.y,0);
+else
+	md.vx_obs=InterpFromMeshToMesh2d(Vel.(Names.indexname),Vel.(Names.xname),Vel.(Names.yname),Vel.(Names.vxname),md.x,md.y,0);
+	md.vy_obs=InterpFromMeshToMesh2d(Vel.(Names.indexname),Vel.(Names.xname),Vel.(Names.yname),Vel.(Names.vyname),md.x,md.y,0);
+end
+md.vel_obs=sqrt(md.vx_obs.^2+md.vy_obs.^2);
+
+%deal with rifts 
+if md.numrifts,
+	%first, recreate rift segments
+	md=meshyamsrecreateriftsegments(md);
+
+	%using the segments, recreate the penaltypairs
+	for j=1:md.numrifts,
+		rift=md.rifts(j);
+
+		%build normals and lengths of segments:
+		lengths=sqrt((md.x(rift.segments(:,1))-md.x(rift.segments(:,2))).^2 + (md.y(rift.segments(:,1))-md.y(rift.segments(:,2))).^2 );
+		normalsx=cos(atan2((md.x(rift.segments(:,1))-md.x(rift.segments(:,2))) , (md.y(rift.segments(:,2))-md.y(rift.segments(:,1)))));
+		normalsy=sin(atan2((md.x(rift.segments(:,1))-md.x(rift.segments(:,2))) , (md.y(rift.segments(:,2))-md.y(rift.segments(:,1)))));
+
+		%ok, build penaltypairs: 
+		numpenaltypairs=length(rift.segments)/2-1;
+		rift.penaltypairs=zeros(numpenaltypairs,7);
+
+		for i=1:numpenaltypairs,
+			rift.penaltypairs(i,1)=rift.segments(i,2);
+			rift.penaltypairs(i,2)=rift.segments(end-i,2);
+			rift.penaltypairs(i,3)=rift.segments(i,3);
+			rift.penaltypairs(i,4)=rift.segments(end-i,3);
+			rift.penaltypairs(i,5)=normalsx(i)+normalsx(i+1);
+			rift.penaltypairs(i,6)=normalsy(i)+normalsy(i+1);
+			rift.penaltypairs(i,7)=(lengths(i)+lengths(i+1))/2;
+		end
+		%renormalize norms: 
+		norms=sqrt(rift.penaltypairs(:,5).^2+rift.penaltypairs(:,6).^2);
+		rift.penaltypairs(:,5)=rift.penaltypairs(:,5)./norms;
+		rift.penaltypairs(:,6)=rift.penaltypairs(:,6)./norms;
+
+		md.rifts(j)=rift;
+	end
+
+end
Index: /issm/trunk/src/m/model/mesh/reorder.m
===================================================================
--- /issm/trunk/src/m/model/mesh/reorder.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/reorder.m	(revision 5901)
@@ -0,0 +1,30 @@
+function md=reorder(md)
+%REORDER - reorder nodes and elements of a model
+%
+%   Usage: 
+%      md=reorder(md)
+
+%some checks
+if md.counter<1,
+	error('reorder error message: no existing mesh, exiting...')
+end
+if md.dim==3,
+	error('reorder error message: 3d models not supported yet, exiting...')
+end
+disp('reorder warning: only the mesh fields are reorder. The model needs to be reparameterized');
+
+%reorder elements
+newelements=randperm(md.numberofelements)';
+tnewelements=zeros(md.numberofelements,1);tnewelements(newelements)=[1:md.numberofelements]';
+
+%reorder nodes
+newgrids=randperm(md.numberofgrids)';
+tnewgrids=zeros(md.numberofgrids,1);tnewgrids(newgrids)=[1:md.numberofgrids]';
+
+%update all fields
+md.elements=tnewgrids(md.elements(newelements,:));
+md.segments=[tnewgrids(md.segments(:,1)) tnewgrids(md.segments(:,2)) tnewelements(md.segments(:,3))];
+md.x=md.x(newgrids);
+md.y=md.y(newgrids);
+md.z=md.z(newgrids);
+md.gridonboundary=zeros(md.numberofgrids,1); md.gridonboundary(md.segments(:,1:2))=1;
Index: /issm/trunk/src/m/model/mesh/rifts/meshaddrifts.m
===================================================================
--- /issm/trunk/src/m/model/mesh/rifts/meshaddrifts.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/rifts/meshaddrifts.m	(revision 5901)
@@ -0,0 +1,96 @@
+function md=meshaddrifts(md,riftname);
+%MESHADDRIFTS - add rifts to a preloaded mesh (typically, an argus mesh)
+%
+%   Usage:
+%      md=meshaddrifts(md,riftname);
+%
+%        where md is a model with a preexisting mesh, and riftname is the name of an .exp file.
+%        The format of the riftname file is as follows: a list of pairs of closed and open contours. 
+%        The closed contour defines the envelop of the rift, the open contour that follows in the 
+%        file defines the rift. The density of the rift should be chosen carefully in the file, as it 
+%        will be used to define the rift contour density of the mesh. The open contour density will 
+%        be preserved. There can be as many pairs of closed contour and rift contour as wished.
+
+
+%read rift: 
+domains=expread(riftname,1);
+contours=domains(1:2:end);
+rifts=domains(2:2:end);
+
+%now loop over rifts: 
+for rift_i=1:length(rifts),
+	
+	%refine rift to desired resolution: 
+	contour=contours(rift_i);
+	rift=rifts(rift_i);
+	
+	delete('Meshaddrifts.Rift.exp');
+	expwrite(rift,'Meshaddrifts.Rift.Coarse.exp');
+	expcoarsen('Meshaddrifts.Rift.exp','Meshaddrifts.Rift.Coarse.exp',rift.density);
+	delete('Meshaddrifts.Rift.Coarse.exp');
+	
+	%extract model:
+	expwrite(contour,'Meshaddrifts.Contour.exp');
+	md2=modelextract(md,'Meshaddrifts.Contour.exp');
+	
+	%create domain of md2 model: 
+	md2.segments=contourenvelope(md2,'Meshaddrifts.Contour.exp');
+	domain_index=md2.segments(1,1:2);
+	while (domain_index(end)~=domain_index(1)),
+		pos=find(md2.segments(:,1)==domain_index(end));
+		domain_index(end+1)=md2.segments(pos,2);
+	end
+	
+	domain.x=md2.x(domain_index);
+	domain.y=md2.y(domain_index);
+	domain.name='Meshaddrifts.Domain.exp';
+	domain.density=1;
+	expwrite(domain,'Meshaddrifts.Domain.exp');
+	
+	%unloop domain index: used for later.
+	domain_index=domain_index(1:end-1);
+	
+	%remesh md2 using new domain outline, and rift profile: 
+	md2=meshnodensity(md2,'Meshaddrifts.Domain.exp','Meshaddrifts.Rift.exp');
+	md2=meshprocessrifts(md2);
+	
+	%plug md2 mesh into md mesh: 
+	[md.elements,md.x,md.y,md.z,md.numberofelements,md.numberofgrids,elconv,nodeconv,elconv2,nodeconv2]=meshplug(md.elements,md.x,md.y,md.z,...
+								md2.elements,md2.x,md2.y,md2.z,md2.extractedgrids,md2.extractedelements,domain_index);
+
+	%update md2 rifts using elconv and nodeconv, and plug them into md: 
+	md2.rifts=updateriftindexing(md2.rifts,elconv2,nodeconv2);
+	
+	for i=1:md.numrifts,
+		md.rifts(i)=updateriftindexing(md.rifts(i),elconv,nodeconv);
+	end
+	
+	if md.numrifts==0,
+		md.rifts=md2.rifts;
+		md.numrifts=1;
+	else
+		md.rifts(end+1,1)=md2.rifts;
+		md.numrifts=md.numrifts+1;
+	end
+	
+	md.segments(:,1:2)=nodeconv(md.segments(:,1:2));
+	md.segments(:,3)=elconv(md.segments(:,3));
+
+end
+
+%finish up "a la" mesh.h
+md.gridonboundary=zeros(md.numberofgrids,1); md.gridonboundary(md.segments(:,1:2))=1;
+md.gridonbed=ones(md.numberofgrids,1);
+md.gridonsurface=ones(md.numberofgrids,1);
+md.elementonbed=ones(md.numberofelements,1);
+md.elementonsurface=ones(md.numberofelements,1);
+
+%Now, build the connectivity tables for this mesh.
+md.nodeconnectivity=NodeConnectivity(md.elements,md.numberofgrids);
+md.elementconnectivity=ElementConnectivity(md.elements,md.nodeconnectivity);
+
+%type of model
+md.dim=2;
+	
+%augment counter  keeping track of what has been done to this model
+md.counter=1;
Index: /issm/trunk/src/m/model/mesh/rifts/meshplug.m
===================================================================
--- /issm/trunk/src/m/model/mesh/rifts/meshplug.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/rifts/meshplug.m	(revision 5901)
@@ -0,0 +1,89 @@
+function [elements,x,y,z,numberofelements,numberofgrids,elconv,nodeconv,elconv2,nodeconv2]=meshplug(elements,x,y,z,elements2,x2,y2,z2,extractedgrids,extractedelements,domain);
+%MESHPLUG - embed mesh into another one
+%     See also meshaddrifts
+
+
+%initialize elconv,nodeconv conversion tables from md mesh to new md mesh
+elconv=1:size(elements,1); elconv=elconv';
+nodeconv=1:size(x,1); nodeconv=nodeconv';
+
+%take away old elements in area of interest: 
+elements(extractedelements,:)=[];
+element_offset=size(elements,1);
+
+%update elconv after having extracted the area of interest elements
+temp_elconv=elconv; temp_elconv(extractedelements)=[];
+temp_elconvnum=1:length(temp_elconv);
+elconv(temp_elconv)=temp_elconvnum;
+elconv(extractedelements)=NaN;
+
+%initialize elconv2 and nodeconv2, conversion tables from md2 mesh to new md mesh
+elconv2=1:size(elements2,1);elconv2=elconv2'+element_offset;
+nodeconv2=(size(x,1)+1):(size(x,1)+size(x2,1)); nodeconv2=nodeconv2';
+
+extractedgrids_minusborder=extractedgrids;
+extractedgrids_minusborder(domain)=[];
+
+x(extractedgrids_minusborder)=NaN;
+y(extractedgrids_minusborder)=NaN;
+
+%now, plug md2 mesh: 
+
+%first, offset all ids of md2 mesh
+elements2=elements2+length(x);
+
+%NaN border grids in second mesh
+x2(1:length(domain))=NaN;
+y2(1:length(domain))=NaN;
+
+%redirect border grids in elements2  to elements
+for i=1:length(domain),
+	pos=find(elements2==(i+length(x)));
+	elements2(pos)=extractedgrids(domain(i));
+end
+
+%same deal for nodeconv2:
+for i=1:length(domain),
+	nodeconv2(i)=extractedgrids(domain(i));
+end
+
+
+%plug elements
+elements=[elements;elements2];
+
+
+%now, increase number of grids
+x=[x; x2];
+y=[y; y2];
+z=[z; z2];
+
+%now, get rid of NaN in x:
+while  ~isempty(find(isnan(x))),
+
+	pos=find(isnan(x));
+	grid=pos(1);
+
+	%collapse grid
+	x(grid)=[];
+	y(grid)=[];
+	z(grid)=[];
+
+	%renumber all grids > grid in elements
+	pos=find(elements>grid);
+	elements(pos)=elements(pos)-1;
+
+	%same deal for nodeconv2: 
+	pos=find(nodeconv2>grid);
+	nodeconv2(pos)=nodeconv2(pos)-1;
+
+end
+
+numberofgrids=length(x);
+numberofelements=length(elements);
+
+%finish nodeconv: 
+temp_nodeconv=nodeconv;  temp_nodeconv(extractedgrids_minusborder)=[];
+temp_nodeconvnum=1:length(temp_nodeconv);
+nodeconv(temp_nodeconv)=temp_nodeconvnum;
+nodeconv(extractedgrids_minusborder)=NaN;
+
Index: /issm/trunk/src/m/model/mesh/rifts/meshprocessoutsiderifts.m
===================================================================
--- /issm/trunk/src/m/model/mesh/rifts/meshprocessoutsiderifts.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/rifts/meshprocessoutsiderifts.m	(revision 5901)
@@ -0,0 +1,94 @@
+function md=meshprocessoutsiderifts(md,domainoutline)
+%MESHPROCESSOUTSIDERIFTS - process rifts when they touch the domain outline
+%
+%   Usage:
+%      md=meshprocessoutsiderifts(md,domain)
+%
+
+
+
+%go through rifts, and figure out which ones touch the domain outline
+for i=1:md.numrifts,
+	
+	%first, flag nodes that belong to the domain outline
+	flags=ContourToMesh(md.elements,md.x,md.y,domainoutline,'node',0);
+
+	rift=md.rifts(i);
+	tips=rift.tips;
+	outsidetips=tips(find(flags(rift.tips)==0));
+
+	%we have found outsidetips, tips that touch the domain outline. go through them
+	for j=1:length(outsidetips),
+		
+		tip=outsidetips(j);
+		%find tip in the segments, take first segment (there should be 2) that holds tip, 
+		%and grid_connected_to_tip is the other node on this segment:
+		tipindex=find(rift.segments(:,1)==tip); 
+		if length(tipindex),
+			tipindex=tipindex(1);
+			grid_connected_to_tip=rift.segments(tipindex,2);
+		else
+			tipindex=find(rift.segments(:,2)==tip); tipindex=tipindex(1);
+			grid_connected_to_tip=rift.segments(tipindex,1);
+		end
+
+		%ok, we have the tip node, and the first node connected to it, on the rift. Now, 
+		%identify all the elements that are connected to the tip, and that are on the same 
+		%side of the rift.
+		A=tip;
+		B=grid_connected_to_tip;
+
+		elements=[];
+
+		while  flags(B), %as long as B does not belong to the domain outline, keep looking.
+			%detect elements on edge A,B:
+			edgeelements=ElementsFromEdge(md.elements,A,B);
+			%rule out those we already detected
+			already_detected=ismember(edgeelements,elements);
+			nextelement=edgeelements(find(~already_detected));
+			%add new detected element to the list of elements we are looking for.
+			elements=[elements;nextelement];
+			%new B:
+			B=md.elements(nextelement,find(~ismember(md.elements(nextelement,:),[A B])));
+		end
+		
+		%take the list of elements on one side of the rift that connect to the tip, 
+		%and duplicate the tip on them, so as to open the rift to the outside.
+		num=length(md.x)+1;
+		md.x=[md.x;md.x(tip)];
+		md.y=[md.y;md.y(tip)];
+		md.numberofgrids=num;
+		
+		%replace tip in elements
+		newelements=md.elements(elements,:);
+		pos=find(newelements==tip);
+		newelements(pos)=num;
+		md.elements(elements,:)=newelements;
+		md.rifts(i).tips=[md.rifts(i).tips num];
+
+		%deal with segments
+		tipsegments=find((md.segments(:,1)==tip) | (md.segments(:,2)==tip));
+		for  k=1:length(tipsegments),
+			segment_index=tipsegments(k);
+			pos=find(md.segments(segment_index,1:2)~=tip);
+			other_node=md.segments(segment_index,pos);
+			if ~isconnected(md.elements,other_node,tip),
+				pos=find(md.segments(segment_index,1:2)==tip);
+				md.segments(segment_index,pos)=num;
+			end
+		end
+	end
+end
+
+
+%Fill in rest of fields:
+md.numberofelements=length(md.elements);
+md.numberofgrids=length(md.x);
+md.z=zeros(md.numberofgrids,1);
+md.gridonboundary=zeros(length(md.x),1); md.gridonboundary(md.segments(:,1:2))=1;
+md.numrifts=length(md.rifts);
+md.elements_type=3*ones(md.numberofelements,1);
+md.gridonbed=ones(md.numberofgrids,1);
+md.gridonsurface=ones(md.numberofgrids,1);
+md.elementonbed=ones(md.numberofelements,1);
+md.elementonsurface=ones(md.numberofelements,1);
Index: /issm/trunk/src/m/model/mesh/rifts/meshprocessrifts.m
===================================================================
--- /issm/trunk/src/m/model/mesh/rifts/meshprocessrifts.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/rifts/meshprocessrifts.m	(revision 5901)
@@ -0,0 +1,67 @@
+function md=meshprocessrifts(md,domainoutline)
+%MESHPROCESSRIFTS - process mesh when rifts are present
+%
+%   split rifts inside mesh (rifts are defined by presence of
+%   segments inside the domain outline)
+%   if domain outline is provided, check for rifts that could touch it, and open them up.
+%
+%   Usage:
+%      md=meshprocessrifts(md,domainoutline)
+%
+%   Ex: 
+%      md=meshprocessrifts(md,'DomainOutline.exp');
+%
+
+%some checks on arguments: 
+if nargout~=1,
+	help meshprocessrifts
+	error('meshprocessrifts usage error:');
+end
+
+if nargin~=2,
+	help meshprocessrifts
+	error('meshprocessrifts usage error:');
+end
+
+%Call MEX file
+[md.elements,md.x,md.y,md.segments,md.segmentmarkers,md.rifts]=TriMeshProcessRifts(md.elements,md.x,md.y,md.segments,md.segmentmarkers);
+
+%Fill in rest of fields:
+md.numberofelements=length(md.elements);
+md.numberofgrids=length(md.x);
+md.z=zeros(md.numberofgrids,1);
+md.gridonboundary=zeros(length(md.x),1); md.gridonboundary(md.segments(:,1:2))=1;
+md.numrifts=length(md.rifts);
+md.elements_type=3*ones(md.numberofelements,1);
+md.gridonbed=ones(md.numberofgrids,1);
+md.gridonsurface=ones(md.numberofgrids,1);
+md.elementonbed=ones(md.numberofelements,1);
+md.elementonsurface=ones(md.numberofelements,1);
+
+%get coordinates of rift tips
+for i=1:md.numrifts,
+	md.rifts(i).tip1coordinates=[md.x(md.rifts(i).tips(1)) md.y(md.rifts(i).tips(1))];
+	md.rifts(i).tip2coordinates=[md.x(md.rifts(i).tips(2)) md.y(md.rifts(i).tips(2))];
+end
+
+%In case we have rifts that open up the domain outline, we need to open them: 
+flags=ContourToMesh(md.elements,md.x,md.y,domainoutline,'node',0);
+found=0;
+for i=1:md.numrifts,
+	if flags(md.rifts(i).tips(1))==0,
+		found=1;
+		break;
+	end
+	if flags(md.rifts(i).tips(2))==0,
+		found=1;
+		break;
+	end
+end
+if found,
+	md=meshprocessoutsiderifts(md,domainoutline);
+end
+
+%get elements that are not correctly oriented in the correct direction:
+aires=GetAreas(md.elements,md.x,md.y);
+pos=find(aires<0);
+md.elements(pos,:)=[md.elements(pos,2) md.elements(pos,1) md.elements(pos,3)];
Index: /issm/trunk/src/m/model/mesh/rifts/meshyamsrecreateriftsegments.m
===================================================================
--- /issm/trunk/src/m/model/mesh/rifts/meshyamsrecreateriftsegments.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/rifts/meshyamsrecreateriftsegments.m	(revision 5901)
@@ -0,0 +1,90 @@
+function md=meshyamsrecreateriftsegments(md)
+
+	%recreate rift segments: just used for yams. temporaroy routine.
+	pos_record=[];
+	if md.numrifts,
+		for i=1:md.numrifts,
+			rift=md.rifts(i);
+
+			%closed rifts first:
+			if length(rift.tips)==2,
+
+				%find tip1 and tip2 for this rift, in the new mesh created by yams.
+				pos=find_point(md.x(md.segments(:,1)),md.y(md.segments(:,1)),rift.tip1coordinates(1),rift.tip1coordinates(2));
+				tip1=md.segments(pos,1);
+				pos=find_point(md.x(md.segments(:,1)),md.y(md.segments(:,1)),rift.tip2coordinates(1),rift.tip2coordinates(2));
+				tip2=md.segments(pos,1);
+
+				%start from tip1, and build segments of this rift. 
+				pos=find_point(md.x(md.segments(:,1)),md.y(md.segments(:,1)),rift.tip1coordinates(1),rift.tip1coordinates(2));
+				pos_record=[pos_record; pos];
+				riftsegs=md.segments(pos,:);
+				while 1,
+					A=riftsegs(end,1); B=riftsegs(end,2); el=riftsegs(end,3);
+					%find other segment that holds B.
+					pos=find(md.segments(:,1)==B);
+					pos_record=[pos_record; pos];
+					riftsegs=[riftsegs; md.segments(pos,:)];
+					if riftsegs(end,2)==tip1, 
+						break;
+					end
+				end
+				md.rifts(i).segments=riftsegs;
+				md.rifts(i).tips=[tip1 tip2];
+
+			else
+				%ok, this is a rift that opens up to the domain outline.  One tip is going to be 
+				%double, the other one, single. We are going to start from the single tip, towards the two 
+				%other doubles
+
+				%find tip1 and tip2 for this rift, in the new mesh created by yams.
+				pos1=find_point(md.x(md.segments(:,1)),md.y(md.segments(:,1)),rift.tip1coordinates(1),rift.tip1coordinates(2));
+				tip1=md.segments(pos1,1);
+				pos2=find_point(md.x(md.segments(:,1)),md.y(md.segments(:,1)),rift.tip2coordinates(1),rift.tip2coordinates(2));
+				tip2=md.segments(pos2,1);
+				if length(tip1)==2,
+					%swap.
+					temp=tip1; tip1=tip2; tip2=temp;
+					temp=pos1; pos1=pos2; pos2=temp;
+					pos=pos1;
+				else
+					pos=pos1;
+				end
+
+				pos_record=[pos_record; pos];
+				riftsegs=md.segments(pos,:);
+				while 1,
+					A=riftsegs(end,1); B=riftsegs(end,2); el=riftsegs(end,3);
+					%find other segment that holds B.
+					pos=find(md.segments(:,1)==B);
+					pos_record=[pos_record; pos];
+					riftsegs=[riftsegs; md.segments(pos,:)];
+					if ((riftsegs(end,2)==tip2(1)) | (riftsegs(end,2)==tip2(2))), 
+						%figure out which tip we reached
+						if riftsegs(end,2)==tip2(1), index=2; else index=1; end
+						break;
+					end
+				end
+
+				%ok, now, we start from the other tip2, towards tip1
+				pos=pos2(index);
+				pos_record=[pos_record; pos];
+				riftsegs=[riftsegs; md.segments(pos,:)];
+				while 1,
+					A=riftsegs(end,1); B=riftsegs(end,2); el=riftsegs(end,3);
+					%find other segment that holds B.
+					pos=find(md.segments(:,1)==B);
+					pos_record=[pos_record; pos];
+					riftsegs=[riftsegs; md.segments(pos,:)];
+					if riftsegs(end,2)==tip1, 
+						break;
+					end
+				end
+				md.rifts(i).segments=riftsegs;
+				md.rifts(i).tips=[tip1 tip2(1) tip2(2)];
+
+			end
+		end
+	end
+	%take out rift segments from segments
+	md.segments(pos_record,:)=[];
Index: /issm/trunk/src/m/model/mesh/rifts/rifttipsrefine.m
===================================================================
--- /issm/trunk/src/m/model/mesh/rifts/rifttipsrefine.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/rifts/rifttipsrefine.m	(revision 5901)
@@ -0,0 +1,26 @@
+function md=rifttipsrefine(md,filename,resolution,circleradius);
+%RIFTTIPSREFINE - refine mesh near rift tips
+%
+%   Usage:
+%      md=rifttipsrefine(md,filename,resolution,circleradius);
+
+numberofgrids=50;
+
+%take rifts, and create refinement circles around tips
+rifts=expread(filename,1);
+
+!echo -n "" > Circles.exp
+for i=1:length(rifts),
+	tip1=[rifts(i).x(1) rifts(i).y(1)];
+	tip2=[rifts(i).x(end) rifts(i).y(end)];
+	%create circle around tip
+	expcreatecircle('Circle1.exp',tip1(1),tip1(2),circleradius,numberofgrids);
+	expcreatecircle('Circle2.exp',tip2(1),tip2(2),circleradius,numberofgrids);
+	!cat Circles.exp Circle1.exp Circle2.exp > Circles2.exp
+	!mv Circles2.exp Circles.exp
+	!rm -rf Circle1.exp Circle2.exp
+end
+
+md=meshexprefine(md,'Circles.exp',resolution);
+
+system('rm -rf Circles.exp');
Index: /issm/trunk/src/m/model/mesh/rifts/updateriftindexing.m
===================================================================
--- /issm/trunk/src/m/model/mesh/rifts/updateriftindexing.m	(revision 5901)
+++ /issm/trunk/src/m/model/mesh/rifts/updateriftindexing.m	(revision 5901)
@@ -0,0 +1,11 @@
+function rift=updateriftindexing(rift,elconv,nodeconv)
+%UPDATERIFTINDEXING - update rift indexing, using mesh to new mesh conversion tables
+%     See also meshaddrift
+
+rift.segments(:,1:2)=nodeconv(rift.segments(:,1:2));
+rift.segments(:,3)=elconv(rift.segments(:,3));
+rift.pairs=elconv(rift.pairs);
+rift.tips=nodeconv(rift.tips);
+
+rift.penaltypairs(:,1:2)=nodeconv(rift.penaltypairs(:,1:2));
+rift.penaltypairs(:,3:4)=elconv(rift.penaltypairs(:,3:4));
Index: /issm/trunk/src/m/model/misfit.m
===================================================================
--- /issm/trunk/src/m/model/misfit.m	(revision 5901)
+++ /issm/trunk/src/m/model/misfit.m	(revision 5901)
@@ -0,0 +1,17 @@
+function J=misfit(md)
+%MISFIT - compute misfit
+%
+%   Usage:
+%      J=misfti(md)
+%
+%   Example:
+%      J=misfti(md)
+%
+
+
+areas=GetAreas(md.elements,md.x,md.y);
+
+deltav=1/2*(   (md.vx-md.vx_obs).^2+(md.vy-md.vy_obs).^2)/md.yts^2;
+deltav_elem=deltav(md.elements)*[1;1;1]/3;
+
+J=sum(deltav_elem.*areas);
Index: /issm/trunk/src/m/model/model2ocmodel.m
===================================================================
--- /issm/trunk/src/m/model/model2ocmodel.m	(revision 5901)
+++ /issm/trunk/src/m/model/model2ocmodel.m	(revision 5901)
@@ -0,0 +1,26 @@
+function md2=model2ocmodel(md,repository)
+%MODEL2OCMODEL - create an out of core model
+%
+%   This routine will take an input model, running in core (ie: md.repository=''),
+%   and copy all its fields to an output model which will run out of core on 'repository'.
+%
+%   Usage:
+%      md2=model2ocmodel(md,repository);
+%
+%   Example:
+%      md2=model2ocmodel(md,'PineIsland');
+
+md2=model(repository);
+
+structfields=fields(md);
+for i=1:length(structfields),
+	field=structfields(i);field=field{1};
+	if strcmpi(field,'repository'),
+		%we don't want to clobber md2.repository!
+		continue;
+	end
+	fieldval=getfield(md,field);
+	if isfield(struct(md2),field),
+	eval(['md2.' field '=fieldval;']);
+	end
+end
Index: /issm/trunk/src/m/model/modeldefault/defaultparams.m
===================================================================
--- /issm/trunk/src/m/model/modeldefault/defaultparams.m	(revision 5901)
+++ /issm/trunk/src/m/model/modeldefault/defaultparams.m	(revision 5901)
@@ -0,0 +1,113 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Some hardcoded parameters for this deck%%%%%%%%%%
+
+%some parameterization for this parameter file :)
+thicknesspath=options.thicknesspath;
+firnpath=options.firnpath;
+surfacepath=options.surfacepath;
+mosaicpath=options.mosaicpath;
+temperaturepath=options.temperaturepath;
+heatfluxpath=options.heatfluxpath;
+
+%Solution parameters
+
+	%parallelization 
+	md.cluster=oshostname();
+	md.np=8;
+	md.time=60;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+	
+	disp('      reading bedmap thicknesses');
+	md.thickness=InterpFromFile(md.x,md.y,thicknesspath,10);
+
+	disp('      reading firn layer');
+	md.firn_layer=InterpFromFile(md.x,md.y,firnpath,0);
+
+	disp('      reading Bamber dem');
+	md.surface=InterpFromFile(md.x,md.y,surfacepath,10);
+
+	%correct the surface by taking into account the firn layer
+	rho_ice=917;
+	rho_firn=830;
+	firn_layer_correction=md.firn_layer*(1-rho_firn/rho_ice);
+	md.surface=md.surface-firn_layer_correction;
+	
+	%Correct thickness by assuming hydrostatic equilibrium 10km down the grounding line
+	md=ThicknessCorrection(md);
+
+	%some corrections
+	minsurf=1;
+	pos=find(isnan(md.surface) | (md.surface<=0));
+	md.surface(pos)=minsurf;
+	pos=find(isnan(md.thickness) | (md.thickness<=0));
+	md.thickness(pos)=minsurf/(1-md.rho_ice/md.rho_water);
+	md.bed=md.surface-md.thickness;
+
+	disp('      reading velocities from Rignot');
+	md=plugvelocities(md,mosaicpath,0);
+	
+	%drag md.drag or stress
+	md.drag_type=2; %0 none 1 plastic 2 viscous
+	md.drag_coefficient=300*ones(md.numberofgrids,1); %q=1.
+		
+	%zones of high md.drag
+	%[rhighmd.drag_coefficient]=ArgusContourToMesh(md.elements,md.x,md.y,'HighDrag.exp','node');
+	%pos=find(highmd.drag);md.drag_coefficient(pos)=10^3;
+
+	%Take care of iceshelves: no drag md.drag_coefficient
+	pos=find(md.elementoniceshelf);
+	md.drag_coefficient(md.elements(pos,:))=0;
+	md.drag_p=ones(md.numberofelements,1);
+	md.drag_q=ones(md.numberofelements,1);
+
+	%Load md.temperature from Giovinetto:
+	disp('      loading temperature');
+	md.temperature=InterpFromFile(md.x,md.y,temperaturepath,253);
+	while ~isempty(find(isnan(md.temperature))),
+		pos=find(isnan(md.temperature));
+		if ((pos+1)<=length(md.temperature)),
+			md.temperature(pos)=md.temperature(pos+1);
+		else
+			md.temperature(pos)=md.temperature(pos-1);
+		end
+	end
+
+	%flow law
+	disp('      creating flow law paramters');
+	md.rheology_n=3*ones(md.numberofelements,1);
+	md.rheology_B=paterson(md.temperature);
+
+	%zones of shear margin softening
+	%[rweakb]=ArgusContourToMesh(md.elements,md.x,md.y,'Weakmd.BPIG.exp','node');
+	%pos=find(weakb);md.rheology_B(pos)=.3*md.rheology_B(pos);
+		
+	%rifts: none for now.
+	%if isstruct(rifts), %we have rifts, choose whether they are full of water or air.
+	%	for i=1:length(rifts), 
+	%		rifts(i).fill='water'; %choice:'air','water','ice'
+	%		rifts(i).friction=10^11;
+	%	end
+	%end
+
+	disp('      creating accumulation rates');
+	md.accumulation_rate=ones(md.numberofgrids,1); %1m/a
+	
+	%Deal with boundary conditions:
+
+	disp('      thermal model');
+	md.melting_rate=zeros(md.numberofgrids,1);
+	md.observed_temperature=md.temperature;
+	
+	disp('      reading geothermal flux');
+	load(heatfluxpath);
+	md.geothermalflux=InterpFromGridToMesh(x_m,y_m,heatflux_Antarctica,md.x,md.y,80);
+	pos=find(md.geothermalflux==0);md.geothermalflux(pos)=80;
+	md.geothermalflux=md.geothermalflux/1000; %map is given in mW/m^2, we need it in W/m^2
+
+	disp('      boundary conditions');
+	md=SetMarineIceSheetBC(md);
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+md.counter=3;
Index: /issm/trunk/src/m/model/modeldefault/modeldefault.m
===================================================================
--- /issm/trunk/src/m/model/modeldefault/modeldefault.m	(revision 5901)
+++ /issm/trunk/src/m/model/modeldefault/modeldefault.m	(revision 5901)
@@ -0,0 +1,66 @@
+function md=modeldefault(varargin),
+%MODELDEFAULT - build a model with default parameters
+%
+%   This routine is used to create and parameterize a model.
+%   Several options are available, but only the domain outline
+%   is mandatory.
+%   Default options will be applied when not specified.
+%
+%   Available options:
+%      o 'domainoutline' followed by the name of an ARGUS file
+%        describing the domain to be meshed
+%      o 'resolution': mesh resolution
+%      o 'iceshelves': ice shelves contours in an ARGUS file
+%      o 'islands': islands contours in an ARGUS file
+%      o 'thicknesspath': path to the thickness data file
+%      o 'firnpath': path to the thickness data file
+%      o 'surfacepath': path to the thickness data file
+%      o 'velocitypath': path to the thickness data file
+%      o 'temperaturepath': path to the thickness data file
+%      o 'heatfluxpath': path to the thickness data file
+%      o 'numlayers': number of layers in the mesh vertical extrusion
+%      o 'extrusionexponent': exponent used in the vertical extrusion
+%      o 'elementstype': type of elements for diagnostic runs
+%
+%   Usage:
+%      md=modeldefault(varargin)
+%
+%   Examples:
+%      md=modeldefault('domainoutline','Pig.exp');
+
+%some checks
+if nargout~=1
+	help modeldefault
+	error('modeldefault error message: bad usage')
+end
+
+%recover options
+disp(sprintf('\nRecovering options...\n'));
+options=pairoptions(varargin{:});
+
+%process options
+options=modeldefault_process(options);
+
+%initialize output:
+md=model;
+
+%Mesh the model
+disp(sprintf('\nMesh generation...'));
+md=mesh(md,options.domainoutline,options.resolution);
+
+%geography
+disp(sprintf('Geography...'));
+md=geography(md,options.iceshelves,options.islands);
+
+%parameterization
+disp(sprintf('Model parameterization...'));
+defaultparams;
+
+%extrusion
+disp(sprintf('Mesh extrusion...'));
+md=extrude(md,options.numlayers,options.extrusionexponent);
+
+%elements type
+disp(sprintf('Setting elemtens type...'));
+md=setelementstype(md,options.elementstype,'all');
+disp(sprintf('done'));
Index: /issm/trunk/src/m/model/modeldefault/modeldefault_process.m
===================================================================
--- /issm/trunk/src/m/model/modeldefault/modeldefault_process.m	(revision 5901)
+++ /issm/trunk/src/m/model/modeldefault/modeldefault_process.m	(revision 5901)
@@ -0,0 +1,77 @@
+function optionstruct=modeldefault_process(options),
+%MODELDEFAULT_PROCESS - process modeldefault options
+%
+%   Usage:
+%      optionstruct=modeldefault_process(options)
+
+%retrieve some paths
+global ISSM_DIR
+modeldatapath='/u/astrid-r1b/larour/ModelData';
+
+%initialize output
+optionstruct=struct();
+
+%domainoutline
+optionstruct.domainoutline=getfieldvalue(options,'domainoutline');
+
+%resolution
+optionstruct.resolution=getfieldvalue(options,'resolution',10000);
+disp(sprintf('   %-18s: %g','resolution',optionstruct.resolution));
+
+%iceshelves
+iceshelves=[ISSM_DIR '/../models/Antarctica/Exp_Par/Iceshelves.exp'];
+optionstruct.iceshelves=getfieldvalue(options,'iceshelves',iceshelves);
+disp(sprintf('   %-18s: %s','iceshelves',optionstruct.iceshelves));
+
+%islands
+islands=[ISSM_DIR '/../models/Antarctica/Exp_Par/Islands.exp'];
+optionstruct.islands=getfieldvalue(options,'islands',islands);
+disp(sprintf('   %-18s: %s','islands',optionstruct.islands));
+
+%thicknesspath
+thicknesspath=[modeldatapath '/BedMap/gridded/thickness.mat'];
+optionstruct.thicknesspath=getfieldvalue(options,'thicknesspath',thicknesspath);
+disp(sprintf('   %-18s: %s','thicknesspath',optionstruct.thicknesspath));
+
+%firnpath
+firnpath=[modeldatapath '/BroekeFirn1km/firn.mat'];
+optionstruct.firnpath=getfieldvalue(options,'firnpath',firnpath);
+disp(sprintf('   %-18s: %s','firnpath',optionstruct.firnpath));
+
+%surfacepath
+surfacepath=[modeldatapath '/BamberDEMAntarctica1km/surface_smooth30_lowslope.mat'];
+optionstruct.surfacepath=getfieldvalue(options,'surfacepath',surfacepath);
+disp(sprintf('   %-18s: %s','surfacepath',optionstruct.surfacepath));
+
+%mosaicpath
+mosaicpath=[modeldatapath '/RignotAntarcticaVelMosaicRampErsAlos/RignotAntVel.mat'];
+optionstruct.mosaicpath=getfieldvalue(options,'mosaicpath',mosaicpath);
+disp(sprintf('   %-18s: %s','mosaicpath',optionstruct.mosaicpath));
+
+%temperaturepath
+temperaturepath=[modeldatapath '/GiovinettoZwallyTemperatures92/Giovinetto_Temperatures.mat'];
+optionstruct.temperaturepath=getfieldvalue(options,'temperaturepath',temperaturepath);
+disp(sprintf('   %-18s: %s','temperaturepath',optionstruct.temperaturepath));
+
+%heatfluxpath
+heatfluxpath=[modeldatapath '/HeatfluxAntarctica/RignotHeatFlux.mat'];
+optionstruct.heatfluxpath=getfieldvalue(options,'heatfluxpath',heatfluxpath);
+disp(sprintf('   %-18s: %s','heatfluxpath',optionstruct.heatfluxpath));
+
+%numlayers
+optionstruct.numlayers=getfieldvalue(options,'numlayers',0);
+disp(sprintf('   %-18s: %g','numlayers',optionstruct.numlayers));
+
+%extrusionexponent
+optionstruct.extrusionexponent=getfieldvalue(options,'extrusionexponent',3);
+disp(sprintf('   %-18s: %g','extrusionexponent',optionstruct.extrusionexponent));
+
+
+%elementstype
+if optionstruct.numlayers>0,
+	elementstype='pattyn';
+else
+	elementstype='macayeal';
+end
+optionstruct.elementstype=getfieldvalue(options,'elementstype',elementstype);
+disp(sprintf('   %-18s: %s','elementstype',optionstruct.elementstype));
Index: /issm/trunk/src/m/model/modelextract.m
===================================================================
--- /issm/trunk/src/m/model/modelextract.m	(revision 5901)
+++ /issm/trunk/src/m/model/modelextract.m	(revision 5901)
@@ -0,0 +1,264 @@
+function md2=modelextract(md1,area)
+%modelextract - extract a model according to an Argus contour or flag list
+%
+%   This routine extracts a submodel from a bigger model with respect to a given contour
+%   md must be followed by the corresponding exp file or flags list
+%   It can either be a domain file (argus type, .exp extension), or an array of element flags. 
+%   If user wants every element outside the domain to be 
+%   modelextract2d, add '~' to the name of the domain file (ex: '~Pattyn.exp');
+%   an empty string '' will be considered as an empty domain
+%   a string 'all' will be considered as the entire domain
+%   add an argument 0 if you do not want the elements to be checked (faster)
+%
+%   Usage:
+%      md2=modelextract(md1,area);
+%
+%   Examples:
+%      md2=modelextract(md,'Domain.exp');
+%      md2=modelextract(md,md.elementoniceshelf);
+%
+%   See also: EXTRUDE, COLLAPSE
+
+%some checks
+if ((nargin~=2) | (nargout~=1)),
+	help modelextract
+	error('modelextract error message: bad usage');
+end
+
+%get check option
+if (nargin==3 & varargin{1}==0),
+	checkoutline=0;
+else
+	checkoutline=1;
+end
+
+%first
+flag_elem=FlagElements(md1,area);
+
+%kick out all elements with 3 dirichlets
+spc_elem=find(~flag_elem);
+spc_grid=sort(unique(md1.elements(spc_elem,:)));
+flag=ones(md1.numberofgrids,1);
+flag(spc_grid)=0;
+pos=find(sum(flag(md1.elements),2)==0);
+flag_elem(pos)=0;
+
+%extracted elements and nodes lists
+pos_elem=find(flag_elem);
+pos_grid=sort(unique(md1.elements(pos_elem,:)));
+
+%keep track of some fields
+numberofgrids1=md1.numberofgrids;
+numberofelements1=md1.numberofelements;
+numberofgrids2=length(pos_grid);
+numberofelements2=length(pos_elem);
+flag_grid=zeros(numberofgrids1,1);
+flag_grid(pos_grid)=1;
+
+%Create Pelem and Pgrid (transform old grids in new grids and same thing for the elements)
+Pelem=zeros(numberofelements1,1);
+Pelem(pos_elem)=[1:numberofelements2]';
+Pgrid=zeros(numberofgrids1,1);
+Pgrid(pos_grid)=[1:numberofgrids2]';
+
+%renumber the elements (some grid won't exist anymore)
+elements_1=md1.elements;
+elements_2=elements_1(pos_elem,:);
+elements_2(:,1)=Pgrid(elements_2(:,1));
+elements_2(:,2)=Pgrid(elements_2(:,2));
+elements_2(:,3)=Pgrid(elements_2(:,3));
+if md1.dim==3,
+	elements_2(:,4)=Pgrid(elements_2(:,4));
+	elements_2(:,5)=Pgrid(elements_2(:,5));
+	elements_2(:,6)=Pgrid(elements_2(:,6));
+end
+
+%OK, now create the new model !
+
+	%take every fields from model
+	md2=md1;
+
+	%automatically modify fields
+
+	%loop over model fields
+	model_fields=fields(md1);
+	for i=1:length(model_fields),
+
+		%get field
+		field=md1.(model_fields(i));
+		fieldsize=size(field);
+
+		%size = number of grids * n
+		if fieldsize(1)==numberofgrids1
+			md2.(model_fields(i))=field(pos_grid,:);
+
+		%size = number of elements * n
+		elseif fieldsize(1)==numberofelements1
+			md2.(model_fields(i))=field(pos_elem,:);
+		end
+	end
+
+	%modify some specific fields
+
+	%Mesh
+	md2.numberofelements=numberofelements2;
+	md2.numberofgrids=numberofgrids2;
+	md2.elements=elements_2;
+
+	%uppernodes lowernodes
+	if md1.dim==3
+		md2.uppergrids=md1.uppergrids(pos_grid);
+		pos=find(~isnan(md2.uppergrids));
+		md2.uppergrids(pos)=Pgrid(md2.uppergrids(pos));
+
+		md2.lowergrids=md1.lowergrids(pos_grid);
+		pos=find(~isnan(md2.lowergrids));
+		md2.lowergrids(pos)=Pgrid(md2.lowergrids(pos));
+
+		md2.upperelements=md1.upperelements(pos_elem);
+		pos=find(~isnan(md2.upperelements));
+		md2.upperelements(pos)=Pelem(md2.upperelements(pos));
+
+		md2.lowerelements=md1.lowerelements(pos_elem);
+		pos=find(~isnan(md2.lowerelements));
+		md2.lowerelements(pos)=Pelem(md2.lowerelements(pos));
+	end
+
+	%Initial 2d mesh 
+	if md1.dim==3
+		flag_elem_2d=flag_elem(1:md1.numberofelements2d);
+		pos_elem_2d=find(flag_elem_2d);
+		flag_grid_2d=flag_grid(1:md1.numberofgrids2d);
+		pos_grid_2d=find(flag_grid_2d);
+
+		md2.numberofelements2d=length(pos_elem_2d);
+		md2.numberofgrids2d=length(pos_grid_2d);
+		md2.elements2d=md1.elements2d(pos_elem_2d,:);
+		md2.elements2d(:,1)=Pgrid(md2.elements2d(:,1));
+		md2.elements2d(:,2)=Pgrid(md2.elements2d(:,2));
+		md2.elements2d(:,3)=Pgrid(md2.elements2d(:,3));
+
+		if ~isnan(md2.elements_type2d), md2.elements_type2d=md1.elements_type2d(pos_elem_2d); end;
+		md2.x2d=md1.x(pos_grid_2d);
+		md2.y2d=md1.y(pos_grid_2d);
+		md2.z2d=md1.z(pos_grid_2d);
+	end
+
+	%Edges
+	if size(md2.edges,2)>1, %do not use ~isnan because there are some NaNs...
+		%renumber first two columns
+		pos=find(~isnan(md2.edges(:,4)));
+		md2.edges(:  ,1)=Pgrid(md2.edges(:,1)); 
+		md2.edges(:  ,2)=Pgrid(md2.edges(:,2)); 
+		md2.edges(:  ,3)=Pelem(md2.edges(:,3));
+		md2.edges(pos,4)=Pelem(md2.edges(pos,4));
+		%remove edges when the 2 vertices are not in the domain.
+		md2.edges=md2.edges(find(md2.edges(:,1) & md2.edges(:,2)),:);
+		%Replace all zeros by NaN in the last two columns;
+		pos=find(md2.edges(:,3)==0);
+		md2.edges(pos,3)=NaN;
+		pos=find(md2.edges(:,4)==0);
+		md2.edges(pos,4)=NaN;
+		%Invert NaN of the third column with last column (Also invert first two columns!!)
+		pos=find(isnan(md2.edges(:,3)));
+		md2.edges(pos,3)=md2.edges(pos,4);
+		md2.edges(pos,4)=NaN;
+		values=md2.edges(pos,2);
+		md2.edges(pos,2)=md2.edges(pos,1);
+		md2.edges(pos,1)=values;
+		%Finally remove edges that do not belong to any element
+		pos=find(isnan(md2.edges(:,3)) & isnan(md2.edges(:,4)));
+		md2.edges(pos,:)=[];
+	end
+
+	%Penalties
+	if ~isnan(md2.penalties),
+		for i=1:size(md1.penalties,1);
+			md2.penalties(i,:)=Pgrid(md1.penalties(i,:));
+		end
+		md2.penalties=md2.penalties(find(md2.penalties(:,1)),:);
+	end
+
+	%recreate segments
+	if md1.dim==2
+		md2.nodeconnectivity=NodeConnectivity(md2.elements,md2.numberofgrids);
+		md2.elementconnectivity=ElementConnectivity(md2.elements,md2.nodeconnectivity);
+		md2.segments=contourenvelope(md2);
+		md2.gridonboundary=zeros(numberofgrids2,1); md2.gridonboundary(md2.segments(:,1:2))=1;
+	end
+
+	%Boundary conditions: Dirichlets on new boundary
+	%Catch the elements that have not been extracted
+	orphans_elem=find(~flag_elem);
+	orphans_grid=unique(md1.elements(orphans_elem,:))';
+	%Figure out which grid are on the boundary between md2 and md1
+	gridstoflag1=intersect(orphans_grid,pos_grid);
+	gridstoflag2=Pgrid(gridstoflag1);
+	if ~isnan(md1.spcvelocity),
+		md2.spcvelocity(gridstoflag2,1:3)=1;
+		if ~isnan(md1.vx_obs) & ~isnan(md1.vy_obs)
+			md2.spcvelocity(gridstoflag2,4)=md2.vx_obs(gridstoflag2); 
+			md2.spcvelocity(gridstoflag2,5)=md2.vy_obs(gridstoflag2);
+		else
+			md2.spcvelocity(gridstoflag2,4:5)=zeros(length(gridstoflag2),2);
+			disp(' ')
+			disp('!! modelextract warning: spc values should be checked !!')
+			disp(' ')
+		end
+	end
+	if ~isnan(md1.spctemperature),
+		md2.spctemperature(gridstoflag2,1)=1;
+		if ~isnan(md1.observed_temperature)
+			md2.spctemperature(gridstoflag2,2)=md2.observed_temperature(gridstoflag2); 
+		else
+			md2.spctemperature(gridstoflag2,2)=zeros(length(gridstoflag2),2);
+			disp(' ')
+			disp('!! modelextract warning: spc values should be checked !!')
+			disp(' ')
+		end
+	end
+
+	%Diagnostic
+	if ~isnan(md2.pressureload)
+		md2.pressureload(:,1)=Pgrid(md1.pressureload(:,1)); 
+		md2.pressureload(:,2)=Pgrid(md1.pressureload(:,2)); 
+		md2.pressureload(:,end-1)=Pelem(md1.pressureload(:,end-1));
+		if md1.dim==3
+			md2.pressureload(:,3)=Pgrid(md1.pressureload(:,3)); 
+			md2.pressureload(:,4)=Pgrid(md1.pressureload(:,4)); 
+		end
+		md2.pressureload=md2.pressureload(find(md2.pressureload(:,1) & md2.pressureload(:,2) & md2.pressureload(:,end)),:);
+	end
+
+	%Results fields
+	if isstruct(md1.results),
+		md2.results=struct();
+		solutionfields=fields(md1.results);
+		for i=1:length(solutionfields),
+			%get subfields
+			solutionsubfields=fields(md1.results.(solutionfields(i)));
+			for j=1:length(solutionsubfields),
+				field=md1.results.(solutionfields(i)).(solutionsubfields(j));
+				if length(field)==numberofgrids1,
+					md2.results.(solutionfields(i)).(solutionsubfields(j))=field(pos_grid);
+				elseif length(field)==numberofelements1,
+					md2.results.(solutionfields(i)).(solutionsubfields(j))=field(pos_elem);
+				else
+					md2.results.(solutionfields(i)).(solutionsubfields(j))=field;
+				end
+			end
+		end
+	end
+
+	%reinitialize output parameters
+	md2.viscousheating=NaN;
+	md2.pressure_elem=NaN;
+	md2.stress=NaN;
+	md2.stress_surface=NaN;
+	md2.stress_bed=NaN;
+	md2.deviatoricstress=NaN;
+	md2.strainrate=NaN;
+
+%Keep track of pos_grid and pos_elem
+md2.extractedgrids=pos_grid;
+md2.extractedelements=pos_elem;
Index: /issm/trunk/src/m/model/modelsextract.m
===================================================================
--- /issm/trunk/src/m/model/modelsextract.m	(revision 5901)
+++ /issm/trunk/src/m/model/modelsextract.m	(revision 5901)
@@ -0,0 +1,87 @@
+function md_list=modelsextract(md,flags,minel,varargin)
+%modelsextract - extract several self contained models according to a list of element flags.
+%
+%   The difference between this routine and the modelextract.m routine (without an 's') is that 
+%   as many models are extracted as there are closed contours defined in area. 
+%   This routine is needed for example when doing data assimilation of ice shelves in Antarctica. 
+%   Many independent ice shelves are present, and we don't want data assimilation on one ice shelf 
+%   to be hindered by another totally independent ice shelf.
+%
+%   Usage:
+%      md_list=modelsextract(md,elementfalgs,minel);
+%
+%   Examples:
+%      md_list=modelsextract(md,md.elementoniceshelf,1000);
+%
+%   See also: EXTRUDE, COLLAPSE, MODELEXTRACT
+
+disp('selecting pools of elements');
+%go through flags and build as many independent element flags as there are groups of connected 1s
+%in flags.
+
+%2D or 3D?
+if md.dim==3,
+	numberofelements=md.numberofelements2d; %this will be forgotten when we get out.
+	flags=project2d(md,flags,1);
+else
+	numberofelements=md.numberofelements;
+end
+
+%recover extra arguments: 
+distance=0;
+if nargin==4,
+	distance=varargin{1};
+end
+
+flag_list=cell(0,1);
+
+for i=1:size(flags,1),
+
+	if (flags(i)),
+
+		%ok, we are sure element i is part of a new pool.
+		pool=zeros(numberofelements,1);
+		pool=PropagateFlagsFromConnectivity(md.elementconnectivity,pool,i,flags);
+		flag_list{end+1,1}=pool;
+		
+		%speed up rest of computation by taking pool out of flags: 
+		pos=find(pool);flags(pos)=0;
+
+	end
+end
+
+%go through flag_list and discard any pool of less than minel elements: 
+ex_pos=[];
+for i=1:length(flag_list),
+	if length(find(flag_list{i}))<minel,
+		ex_pos=[ex_pos; i];
+	end
+end
+flag_list(ex_pos)=[];
+
+%now, if distance was specified, expand the flag_list by distance km: 
+if distance,
+	for i=1:length(flag_list),
+		flag_list{i}=PropagateFlagsUntilDistance(md,flag_list{i},distance);
+	end
+end
+
+%now, go use the pools of flags to extract models: 
+disp(['extracting ' num2str(size(flag_list,1)) ' models']);
+models=cell(0,1);
+
+for i=1:size(flag_list,1),
+	disp(['   ' num2str(i) '/' num2str(size(flag_list,1))]);
+	if md.dim==3,
+		flags2d=flag_list{i};
+		realflags=project3d(md,flags2d,'element');
+	else
+		realflags=flag_list{i};
+	end
+	models{end+1,1}=modelextract(md,realflags);
+end
+
+%return model list
+md_list=modellist(models);
+
+end %end of this function
Index: /issm/trunk/src/m/model/modelsextractfromdomains.m
===================================================================
--- /issm/trunk/src/m/model/modelsextractfromdomains.m	(revision 5901)
+++ /issm/trunk/src/m/model/modelsextractfromdomains.m	(revision 5901)
@@ -0,0 +1,27 @@
+function md_list=modelsextractfromdomains(md,directory)
+%modelsextractfromdomains- extract several self contained models according to a list of domains
+%
+%   Usage:
+%      md_list=modelsextractfromdomains(md,'Basins/');
+%
+%   Examples:
+%      md_list=modelsextract(md,'Basins/');
+%
+%   See also: MODELSEXTRACTS, MODELEXTRACT
+
+
+
+%go into directory and get list of files.
+cd(directory);
+basins=listfiles;
+cd ..
+
+models=cell(0,1);
+for i=1:length(basins),
+	models{end+1,1}=modelextract(md,[directory '/' basins{i}]);
+end
+
+%return model list: 
+md_list=modellist(models);
+
+end %end of this function
Index: /issm/trunk/src/m/model/modis.m
===================================================================
--- /issm/trunk/src/m/model/modis.m	(revision 5901)
+++ /issm/trunk/src/m/model/modis.m	(revision 5901)
@@ -0,0 +1,37 @@
+function [xm,ym,modis]=modis(modisgeotif,xlim,ylim)
+%MODIS - from modis geotiff, return image
+%
+%   Usage:
+%      [xm,ym,modis]=modis(modisgeotif,xlim,ylim)
+%
+
+global ISSM_DIR
+
+%find gdal coordinates
+x0=min(xlim);
+x1=max(xlim);
+
+y0=min(ylim);
+y1=max(ylim);
+
+%Get path  to gdal binaries
+path_gdal=[ISSM_DIR '/externalpackages/gdal/install/bin/'];
+
+%Was gdal compiled? 
+if ~exist([path_gdal 'gdal_translate']),
+	error(['modis error message: GDAL library needs to be compiled to use this routine. Compile GDAL in ' ISSM_DIR '/externalpackages/gdal to use this routine.']);
+end
+
+inputname='./temp.tif';
+system([path_gdal 'gdal_translate -quiet -projwin ' num2str(x0) ' ' num2str(y1) ' ' num2str(x1) ' ' num2str(y0) ' ' modisgeotif ' ' inputname ]);
+
+%Read in temp.tif:
+modis=double(flipud(imread('temp.tif','TIFF')));
+xm=(x0:(x1-x0)/(size(md.sarpwr,2)-1):x1);
+ym=(y0:(y1-y0)/(size(md.sarpwr,1)-1):y1);
+
+%Erase image
+system('rm -rf ./temp.tif');
+
+
+end
Index: /issm/trunk/src/m/model/parametercontroloptimization.m
===================================================================
--- /issm/trunk/src/m/model/parametercontroloptimization.m	(revision 5901)
+++ /issm/trunk/src/m/model/parametercontroloptimization.m	(revision 5901)
@@ -0,0 +1,71 @@
+function md=parametercontroloptimization(md,varargin),
+%PARAMETERCONTROLOPTIMIZATION - parameterization for control method on drag
+%
+%   It is possible to specify the number of steps, values for the
+%   minimum and maximum values of the drag, specify a noise dampening, the 
+%   kind of fit to use or the the optscal.
+%   
+%   Usage:
+%       md=parametercontroloptimization(md,varargin)
+%
+%   Example:
+%      md=parametercontroloptimization(md,'nsteps',6)
+
+%process options
+options=pairoptions(varargin{:});
+
+%Copy model
+md2=md;
+
+%Hard coded parameters
+%variable
+cmax_max=1000;
+cm_maxs=linspace(cmax_max/10,cmax_max,3);
+optscal_max=1000;
+optscals=linspace(optscal_max/10,optscal_max,3);
+fits=[0 2];
+%Kept constant
+md2.verbose=0;
+md2.cm_min=1;
+md2.eps_cm=NaN;
+md2.cm_noisedmp=0;
+md2.nsteps=getfieldvalue(options,'nsteps',5);
+md2.control_type=getfieldvalue(options,'md2.control_type',DragCoefficientEnum);
+md2.maxiter=10*ones(md2.nsteps,1);
+md2.cm_jump=0.99*ones(md2.nsteps,1);
+md2.control_analysis=1;
+md2.weights=ones(md2.numberofgrids,1);
+
+%loop over the set of parameters
+best=0;
+count=1;
+for fit=fits,
+	md2.fit=fit*ones(md2.nsteps,1);
+	for cm_max=cm_maxs;
+		md2.cm_max=cm_max;
+		for optscal=optscals;
+			md2.optscal=optscal*ones(md2.nsteps,1);
+
+			%current run
+			disp(sprintf('\n   Step %i/%i, fit=%i, cm_max=%g, optscal=%g\n',count,length(cm_maxs)*length(optscals)*length(fits),fit,cm_max,optscal))
+			md2=solve(md2,'analysis_type','DiagnosticAnalysis');
+			count=count+1;
+
+			%Check misfit difference
+			rel=(md2.results.DiagnosticAnalysis.J(1)-md2.results.DiagnosticAnalysis.J(end))/md2.results.DiagnosticAnalysis.J(1);
+			disp(['   ΔJ/J=' num2str(rel*100) '% for fit=' num2str(fit) ',cm_max=' num2str(cm_max) ', and optscal=' num2str(optscal) ]);
+			if (rel>best),
+				disp(sprintf('   --> current best'))
+				fit_final    =md2.fit;
+				cmmax_final  =md2.cm_max;
+				optscal_final=md2.optscal;
+				best=rel;
+			end
+		end
+	end
+end
+
+%load final parameters onto initial model
+md.fit    =fit_final;
+md.cm_max =cmmax_final;
+md.optscal=optscal_final;
Index: /issm/trunk/src/m/model/parameterization/parametercontrolB.m
===================================================================
--- /issm/trunk/src/m/model/parameterization/parametercontrolB.m	(revision 5901)
+++ /issm/trunk/src/m/model/parameterization/parametercontrolB.m	(revision 5901)
@@ -0,0 +1,125 @@
+function md=parametercontrolB(md,varargin),
+%PARAMETERCONTROLB - parameterization for control method on B
+%
+%   It is possible to specify the number of steps, values for the
+%   minimum and maximum values of B, specify a noise dampening, the 
+%   kind of cm_responses to use or the the optscal.
+%   
+%   Usage:
+%       md=parametercontrolB(md,varargin)
+%
+%   Example:
+%      md=parametercontrolB(md)
+%      md=parametercontrolB(md,'nsteps',20,'cm_noisedmp',10^-15,'cm_responses',0)
+%      md=parametercontrolB(md,'cm_min',10,'cm_max',10^8,'cm_jump',0.99,'maxiter',20)
+%      md=parametercontrolB(md,eps_cm',10^-4,'optscal',[10^7 10^8])
+%
+%   See also  PARAMETERCONTROLDRAG
+
+%process options
+options=pairoptions(varargin{:});
+
+%control type
+md.control_type=RheologyBbarEnum;
+
+%weights
+weights=getfieldvalue(options,'weights',ones(md.numberofgrids,1));
+if (length(weights)~=md.numberofgrids)
+	md.weights=ones(md.numberofgrids,1);
+else
+	md.weights=weights;
+end
+
+%nsteps
+nsteps=getfieldvalue(options,'nsteps',100);
+if (length(nsteps)~=1 | nsteps<=0 | floor(nsteps)~=nsteps)
+	md.nsteps=100;
+else
+	md.nsteps=nsteps;
+end
+
+%cm_min
+cm_min=getfieldvalue(options,'cm_min',1);
+if (length(cm_min)~=1)
+	md.cm_min=1;
+else
+	md.cm_min=cm_min;
+end
+
+%cm_max
+cm_max=getfieldvalue(options,'cm_max',10^10);
+if (length(cm_max)~=1)
+	md.cm_max=10^10;
+else
+	md.cm_max=cm_max;
+end
+
+%cm_noisedmp
+cm_noisedmp=getfieldvalue(options,'cm_noisedmp',1*10^-21);
+if (length(cm_noisedmp)~=1)
+	md.cm_noisedmp=1*10^-21;
+else
+	md.cm_noisedmp=cm_noisedmp;
+end
+
+%eps_cm
+eps_cm=getfieldvalue(options,'eps_cm',NaN);
+if (length(eps_cm)~=1 | eps_cm<0 )
+	md.eps_cm=NaN;
+else
+	md.eps_cm=eps_cm;
+end
+
+%maxiter
+maxiter=getfieldvalue(options,'maxiter',10*ones(md.nsteps,1));
+if (any(maxiter<0) | any(floor(maxiter)~=maxiter))
+	md.maxiter=10*ones(md.nsteps,1);
+else
+	md.maxiter=repmat(maxiter(:),md.nsteps,1);
+	md.maxiter(md.nsteps+1:end)=[];
+end
+
+%cm_jump
+cm_jump=getfieldvalue(options,'cm_jump',0.9*ones(md.nsteps,1));
+if ~isreal(cm_jump)
+	md.cm_jump=0.9*ones(md.nsteps,1);
+else
+	md.cm_jump=repmat(cm_jump(:),md.nsteps,1);
+	md.cm_jump(md.nsteps+1:end)=[];
+end
+
+%cm_responses
+found=0;
+if exist(options,'cm_responses'),
+	cm_responses=getfieldvalue(options,'cm_responses');
+	if ~any(~ismember(cm_responses,[ SurfaceAbsVelMisfitEnum, SurfaceRelVelMisfitEnum, SurfaceLogVelMisfitEnum, SurfaceLogVxVyMisfitEnum, SurfaceAverageVelMisfitEnum ]));
+		md.cm_responses=repmat(cm_responses(:),md.nsteps,1);
+		md.cm_responses(md.nsteps+1:end)=[];
+		found=1;
+	end
+end
+if ~found
+	third=ceil(md.nsteps/3);
+	md.cm_responses=[...
+		SurfaceLogVelMisfitEnum*ones(third,1);...
+		SurfaceAbsVelMisfitEnum*ones(third,1);...
+		repmat([SurfaceAbsVelMisfitEnum;SurfaceAbsVelMisfitEnum;SurfaceLogVelMisfitEnum;SurfaceAbsVelMisfitEnum],third,1)...
+		];
+	md.cm_responses(md.nsteps+1:end)=[];
+end
+
+%optscal
+found=0;
+if exist(options,'optscal'),
+	optscal=getfieldvalue(options,'optscal');
+	if ~any(optscal<0),
+		md.optscal=repmat(optscal(:),md.nsteps,1);
+		md.optscal(md.nsteps+1:end)=[];
+		found=1;
+	end
+end
+if ~found
+	third=ceil(md.nsteps/3);
+	md.optscal=[2*10^8*ones(3,1);10^8*ones(third-3,1);10^7*ones(2*third,1);];
+	md.optscal(md.nsteps+1:end)=[];
+end
Index: /issm/trunk/src/m/model/parameterization/parametercontroldrag.m
===================================================================
--- /issm/trunk/src/m/model/parameterization/parametercontroldrag.m	(revision 5901)
+++ /issm/trunk/src/m/model/parameterization/parametercontroldrag.m	(revision 5901)
@@ -0,0 +1,125 @@
+function md=parametercontroldrag(md,varargin),
+%PARAMETERCONTROLDRAG - parameterization for control method on drag
+%
+%   It is possible to specify the number of steps, values for the
+%   minimum and maximum values of the drag, specify a noise dampening, the 
+%   kind of cm_responses to use or the the optscal.
+%   
+%   Usage:
+%       md=parametercontroldrag(md,varargin)
+%
+%   Example:
+%      md=parametercontroldrag(md)
+%      md=parametercontroldrag(md,'nsteps',20,'cm_noisedmp',10^-8,'cm_responses',0)
+%      md=parametercontroldrag(md,'cm_min',1,'cm_max',150,'cm_jump',0.99,'maxiter',20)
+%      md=parametercontroldrag(md,eps_cm',10^-4,'optscal',[10^7 10^8])
+%
+%   See also PARAMETERCONTROLB
+
+%process options
+options=pairoptions(varargin{:});
+
+%control type
+md.control_type=DragCoefficientEnum;
+
+%weights
+weights=getfieldvalue(options,'weights',ones(md.numberofgrids,1));
+if (length(weights)~=md.numberofgrids)
+	md.weights=ones(md.numberofgrids,1);
+else
+	md.weights=weights;
+end
+
+%nsteps
+nsteps=getfieldvalue(options,'nsteps',100);
+if (length(nsteps)~=1 | nsteps<=0 | floor(nsteps)~=nsteps)
+	md.nsteps=100;
+else
+	md.nsteps=nsteps;
+end
+
+%cm_min
+cm_min=getfieldvalue(options,'cm_min',1);
+if (length(cm_min)~=1)
+	md.cm_min=1;
+else
+	md.cm_min=cm_min;
+end
+
+%cm_max
+cm_max=getfieldvalue(options,'cm_max',250);
+if (length(cm_max)~=1)
+	md.cm_max=250;
+else
+	md.cm_max=cm_max;
+end
+
+%cm_noisedmp
+cm_noisedmp=getfieldvalue(options,'cm_noisedmp',2*10^-7);
+if (length(cm_noisedmp)~=1)
+	md.cm_noisedmp=2*10^-7;
+else
+	md.cm_noisedmp=cm_noisedmp;
+end
+
+%eps_cm
+eps_cm=getfieldvalue(options,'eps_cm',NaN);
+if (length(eps_cm)~=1 | eps_cm<0 )
+	md.eps_cm=NaN;
+else
+	md.eps_cm=eps_cm;
+end
+
+%maxiter
+maxiter=getfieldvalue(options,'maxiter',10*ones(md.nsteps,1));
+if (any(maxiter<0) | any(floor(maxiter)~=maxiter))
+	md.maxiter=10*ones(md.nsteps,1);
+else
+	md.maxiter=repmat(maxiter(:),md.nsteps,1);
+	md.maxiter(md.nsteps+1:end)=[];
+end
+
+%cm_jump
+cm_jump=getfieldvalue(options,'cm_jump',0.8*ones(md.nsteps,1));
+if ~isreal(cm_jump)
+	md.cm_jump=0.8*ones(md.nsteps,1);
+else
+	md.cm_jump=repmat(cm_jump(:),md.nsteps,1);
+	md.cm_jump(md.nsteps+1:end)=[];
+end
+
+%cm_responses
+found=0;
+if exist(options,'cm_responses'),
+	cm_responses=getfieldvalue(options,'cm_responses');
+	if ~any(~ismember(cm_responses,[ SurfaceAbsVelMisfitEnum, SurfaceRelVelMisfitEnum, SurfaceLogVelMisfitEnum, SurfaceLogVxVyMisfitEnum, SurfaceAverageVelMisfitEnum ]));
+		md.cm_responses=repmat(cm_responses(:),md.nsteps,1);
+		md.cm_responses(md.nsteps+1:end)=[];
+		found=1;
+	end
+end
+if ~found
+	third=ceil(md.nsteps/3);
+	md.cm_responses=[...
+		SurfaceLogVelMisfitEnum*ones(third,1);...
+		SurfaceAbsVelMisfitEnum*ones(third,1);...
+		repmat([SurfaceAbsVelMisfitEnum;SurfaceAbsVelMisfitEnum;SurfaceLogVelMisfitEnum;SurfaceAbsVelMisfitEnum],third,1)...
+		];
+	md.cm_responses(md.nsteps+1:end)=[];
+end
+
+%optscal
+found=0;
+if exist(options,'optscal'),
+	optscal=getfieldvalue(options,'optscal');
+	if ~any(optscal<0),
+		md.optscal=repmat(optscal(:),md.nsteps,1);
+		md.optscal(md.nsteps+1:end)=[];
+		found=1;
+	end
+end
+if ~found
+	third=ceil(md.nsteps/3);
+	md.optscal=[50*ones(3,1);15*ones(third-3,1);10*ones(third,1);repmat([10;10;20;10],third,1)];
+	md.optscal(md.nsteps+1:end)=[];
+end
Index: /issm/trunk/src/m/model/parameterization/parameterize.m
===================================================================
--- /issm/trunk/src/m/model/parameterization/parameterize.m	(revision 5901)
+++ /issm/trunk/src/m/model/parameterization/parameterize.m	(revision 5901)
@@ -0,0 +1,73 @@
+function md=parameterize(md,parametername)
+%PARAMETERIZE - parameterize a model
+%
+%   from a parameter matlab file, start filling in all the @model fields that were not 
+%   filled in by the mesh.m and geography.m @model methods.
+%   Warning: the paramter file must be able to be run in Matlab
+%
+%   Usage:
+%      md=parameterize(md,parametername)
+%
+%   Example:
+%      md=parameterize(md,'Square.par');
+
+%some checks
+if md.counter>=4,
+	%We need to take this out, as it gets too constraining. 
+	choice=input('This model already has parameters and has been extruded. Are you sure you want to go ahead? (y/n)','s');
+	if ~strcmp(choice,'y')
+		error('no parameters done ... exiting');
+	end
+elseif md.counter==3
+	disp('This model already has parameters, overwriting...')
+else
+	if (md.counter<2)
+		error('parameterize error message: you need to run geography.m first on this model');
+	else
+		md.counter=3;
+	end
+end
+if ~exist(parametername),
+	error(['parameterize error message: file ' parametername ' not found !']);
+end
+
+%Try and run parameter file.
+temporaryname=['TemporaryParameterFile' num2str(GetPId()) ];
+copyfile(parametername,[temporaryname '.m']);
+
+try,
+	eval(temporaryname);
+	delete([temporaryname '.m']);
+catch me,
+	delete([temporaryname '.m']);
+
+	%copy error message
+	me2=struct('message',me.message,'stack',me.stack);
+
+	%rename parameter file
+	for i=1:length(me2.stack)-1,
+		if (strncmp(fliplr(me2.stack(i).file),fliplr([temporaryname '.m']),length(temporaryname)+2))
+			me2.stack(i).file=parametername;
+		end
+		if strcmp(me2.stack(i).name,temporaryname),
+			me2.stack(i).name=parametername;
+		end
+		if strcmp(me2.stack(i).name,temporaryname),
+			%remove parameterize.m error "TemporaryParameterFile" misleading
+			me2.stack(i)=[];
+		end
+	end
+
+	%throw error message
+	rethrow(me2);
+end
+
+%Keep track of parameter file
+md.parameterfile=char(textread(parametername,'%s','delimiter','\n'));
+
+%Name and notes
+if isempty(md.name), 
+	[a,root,c,d]=fileparts(parametername);
+	md.name=root; 
+end
+md=addnote(md,['Model created by using parameter file: ' parametername ' on: ' datestr(now)]);
Index: /issm/trunk/src/m/model/parseresultsfromdisk.m
===================================================================
--- /issm/trunk/src/m/model/parseresultsfromdisk.m	(revision 5901)
+++ /issm/trunk/src/m/model/parseresultsfromdisk.m	(revision 5901)
@@ -0,0 +1,33 @@
+function results=parseresultsfromdisk(filename)
+%PARSERESULTSFROMDISK - ...
+%
+%   Usage:
+%      results=parseresultsfromdisk(filename)
+
+%Open file
+fid=fopen(filename,'rb');
+if(fid==-1),
+	error(['loadresultsfromdisk error message: could not open ',filename,' for binary reading']);
+end
+results=struct();
+
+%Read fields until the end of the file.
+result=ReadData(fid);
+while ~isempty(result),
+
+	%Get time and step
+	results(result.step).step=result.step;
+	results(result.step).time=result.time; 
+
+	%Add result
+	results(result.step).(result.fieldname)=result.field;
+
+	%read next result
+	result=ReadData(fid);
+
+end
+
+%process patch if necessary
+results=MatlabProcessPatch(results);
+
+fclose(fid);
Index: /issm/trunk/src/m/model/partition/AreaAverageOntoPartition.m
===================================================================
--- /issm/trunk/src/m/model/partition/AreaAverageOntoPartition.m	(revision 5901)
+++ /issm/trunk/src/m/model/partition/AreaAverageOntoPartition.m	(revision 5901)
@@ -0,0 +1,18 @@
+function partvector=AreaAverageOntoPartition(md,vector)
+%AREAAVERAGEONTOPARTITION  compute partition values for a certain vector expressed on the vertices of the mesh. Use area weighted average.
+%
+%   Usage: average=AreaAverageOntoPartition(md,vector)
+%
+
+%ok, first check that part is Matlab matlab indexed
+part=md.part+1;
+
+%initialize output
+partvector=zeros(max(part),1);
+
+%start weight average
+weightedvector=vector.*md.vwgt;
+for i=1:max(part),
+	pos=find(part==i);
+	partvector(i)=sum(weightedvector(pos))/sum(md.vwgt(pos));
+end
Index: /issm/trunk/src/m/model/partition/adjacency.m
===================================================================
--- /issm/trunk/src/m/model/partition/adjacency.m	(revision 5901)
+++ /issm/trunk/src/m/model/partition/adjacency.m	(revision 5901)
@@ -0,0 +1,28 @@
+function md=adjacency(md);
+%adjacency:  compute adjacency matrix, list of vertices and list of weights.
+%
+%  function to create the adjacency matrix from the connectivity table.
+%
+%  the required output is:
+%    md.adj_mat     (double [sparse nv x nv], vertex adjacency matrix)
+%    md.vwgt        (double [nv], vertex weights)
+
+
+
+indi=[md.elements(:,1);md.elements(:,2);md.elements(:,3)];
+indj=[md.elements(:,2);md.elements(:,3);md.elements(:,1)];
+values=1;
+
+md.adjacency=sparse(indi,indj,values,md.numberofgrids,md.numberofgrids);
+md.adjacency=double([md.adjacency | md.adjacency']);
+
+%now, build vwgt:
+areas=GetAreas(md.elements,md.x,md.y);
+
+%get node connectivity
+md.nodeconnectivity=NodeConnectivity(md.elements,md.numberofgrids);
+
+connectivity=md.nodeconnectivity(:,1:end-1);
+pos=find(connectivity);
+connectivity(pos)=areas(connectivity(pos))/3;
+md.vwgt=sum(connectivity,2);
Index: /issm/trunk/src/m/model/partition/flagedges.m
===================================================================
--- /issm/trunk/src/m/model/partition/flagedges.m	(revision 5901)
+++ /issm/trunk/src/m/model/partition/flagedges.m	(revision 5901)
@@ -0,0 +1,46 @@
+function [xsegments ysegments]=flagedges(elements,x,y,partition);
+%FLAGEDGES return pairs of x,y segments, delimiting partitions.
+%
+%         Usage: [xsegments ysegments]=flagedges(elements,x,y,partition)
+%
+
+xsegments=[];
+ysegments=[];
+
+for i=1:size(elements,1),
+	m1=partition(elements(i,1));
+	m2=partition(elements(i,2));
+	m3=partition(elements(i,3));
+	x1=x(elements(i,1));
+	x2=x(elements(i,2));
+	x3=x(elements(i,3));
+	y1=y(elements(i,1));
+	y2=y(elements(i,2));
+	y3=y(elements(i,3));
+
+	if (m1~=m2) & (m1~=m3) & (m2~=m3),
+		xmiddle=(x1+x2+x3)/3;
+		ymiddle=(y1+y2+y3)/3;
+		xsegments=[xsegments; (x1+x2)/2 xmiddle];
+		xsegments=[xsegments; (x1+x3)/2 xmiddle];
+		xsegments=[xsegments; (x2+x3)/2 xmiddle];
+		ysegments=[ysegments; (y1+y2)/2 ymiddle];
+		ysegments=[ysegments; (y1+y3)/2 ymiddle];
+		ysegments=[ysegments; (y2+y3)/2 ymiddle];
+	end
+
+	if (m1==m2) & (m1~=m3),
+		xsegments=[xsegments; (x1+x3)/2 (x2+x3)/2];
+		ysegments=[ysegments; (y1+y3)/2 (y2+y3)/2];
+	end
+	if (m1==m3) & (m2~=m3),
+		xsegments=[xsegments; (x1+x2)/2 (x2+x3)/2];
+		ysegments=[ysegments; (y1+y2)/2 (y2+y3)/2];
+	end
+
+	if (m2==m3) & (m1~=m3),
+		xsegments=[xsegments; (x1+x2)/2 (x1+x3)/2];
+		ysegments=[ysegments; (y1+y2)/2 (y1+y3)/2];
+	end
+end
+
Index: /issm/trunk/src/m/model/partition/partitioner.m
===================================================================
--- /issm/trunk/src/m/model/partition/partitioner.m	(revision 5901)
+++ /issm/trunk/src/m/model/partition/partitioner.m	(revision 5901)
@@ -0,0 +1,89 @@
+function md=partitioner(md,varargin)
+%PARTITIONER - partition mesh 
+%
+%   List of options to partitioner: 
+%
+%   package: 'chaco', 'metis' or 'scotch'
+%   npart: number of partitions.
+%   weighting: 'on' or 'off': default off
+%   section:  1 by defaults(1=bisection, 2=quadrisection, 3=octasection)
+%   recomputeadjacency:  'on' by default (set to 'off' to compute existing one)
+%   Output: md.part recover the partition vector
+%   
+%   Usage:
+%      md=partitioner(md,'package','chaco','npart',100,'weighting','on');
+%
+
+
+%get options: 
+options=pairoptions(varargin{:});
+
+%set defaults
+options=addfielddefault(options,'package','chaco');
+options=addfielddefault(options,'npart',10);
+options=addfielddefault(options,'weighting','on');
+options=addfielddefault(options,'section',1);
+options=addfielddefault(options,'recomputeadjacency','on');
+
+%get package: 
+package=getfieldvalue(options,'package');
+npart=getfieldvalue(options,'npart');
+recomputeadjacency=getfieldvalue(options,'recomputeadjacency');
+
+%adjacency matrix if needed:
+if (strcmpi(package,'chaco') || strcmpi(package,'scotch')),
+	if strcmpi(recomputeadjacency,'on'),
+		md=adjacency(md);
+	else
+		disp('skipping adjacency matrix computation as requested in the options');
+	end
+end
+
+
+if strcmpi(package,'chaco'),
+
+	%  default method (from chaco.m)
+	method=[1 1 0 0 1 1 50 0 .001 7654321]';
+	method(1)=3;    %  global method (3=inertial (geometric))
+	method(3)=0;    %  vertex weights (0=off, 1=on)
+	
+	%specify bisection
+	method(6)=getfieldvalue(options,'section');%  ndims (1=bisection, 2=quadrisection, 3=octasection)
+
+	%are we using weights? 
+	if strcmpi(getfieldvalue(options,'weighting'),'on'),
+		weights=floor(md.vwgt/min(md.vwgt));
+		method(3)=1;
+	else 
+		weights=[];
+	end
+	
+	%  partition into nparts
+	part=Chaco(md.adjacency,weights,[],md.x, md.y ,md.z,method,npart,[])'+1; %index partitions from 1 up. like metis.
+
+elseif strcmpi(package,'scotch'),
+
+	%are we using weights? 
+	if strcmpi(getfieldvalue(options,'weighting'),'on'),
+		weights=floor(md.vwgt/min(md.vwgt));
+	end
+	maptab=Scotch(md.adjacency,[],weights,[],'cmplt',[npart]);
+	
+	part=maptab(:,2);%index partitions from 1 up. like metis.
+
+
+elseif strcmpi(package,'linear'),
+
+	part=1:1:md.numberofgrids;
+
+elseif strcmpi(package,'metis'),
+
+	[element_partitioning,part]=MeshPartition(md,npart);
+
+else
+
+	error(['partitioner error message: could not find ' package ' partitioner']);
+	help partitioner
+end
+
+md.part=part;
Index: /issm/trunk/src/m/model/peek.m
===================================================================
--- /issm/trunk/src/m/model/peek.m	(revision 5901)
+++ /issm/trunk/src/m/model/peek.m	(revision 5901)
@@ -0,0 +1,16 @@
+function md=peek(md)
+%PEEK - check on an existing job running on the cluster
+%
+%   Usage:
+%      md=peek(md);
+%
+%   See also: QueueJobPeek
+
+%Get cluster.rc location
+cluster_rc_location=which('cluster.rc');
+
+%Figure out parameters for this particular cluster
+[codepath,executionpath,login]=ClusterParameters(md.cluster,cluster_rc_location);
+
+%peek at the queued job
+md=QueueJobPeek(md,executionpath);
Index: /issm/trunk/src/m/model/plot/applyoptions.m
===================================================================
--- /issm/trunk/src/m/model/plot/applyoptions.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/applyoptions.m	(revision 5901)
@@ -0,0 +1,314 @@
+function applyoptions(md,data,options)
+%APPLYOPTIONS - apply the options to current plot
+%
+%   Usage:
+%      applyoptions(md,data,options)
+%
+%   See also: PLOTMODEL, PARSE_OPTIONS
+
+global ISSM_DIR
+
+%fontsize
+fontsize=getfieldvalue(options,'fontsize',14);
+
+%fontweight
+fontweight=getfieldvalue(options,'fontweight','normal');
+
+%title
+if exist(options,'title')
+	titlevalue=getfieldvalue(options,'title');
+	if iscell(titlevalue),
+		title(titlevalue,'FontSize',fontsize,'FontWeight',fontweight);
+	else
+		if ~isnan(titlevalue),
+			title(titlevalue,'FontSize',fontsize,'FontWeight',fontweight);
+		end
+	end
+end
+
+%xlabel
+if exist(options,'xlabel');
+	xlabel(getfieldvalue(options,'xlabel'),'FontSize',fontsize,'FontWeight',fontweight);
+end
+
+%ylabel
+if exist(options,'ylabel');
+	ylabel(getfieldvalue(options,'ylabel'),'FontSize',fontsize,'FontWeight',fontweight);
+end
+
+%zlabel
+if exist(options,'zlabel');
+	zlabel(getfieldvalue(options,'zlabel'),'FontSize',fontsize,'FontWeight',fontweight);
+end
+
+%xtikcs
+if exist(options,'xtick'), set(gca,'XTick',getfieldvalue(options,'xtick')); end
+if exist(options,'ytick'), set(gca,'YTick',getfieldvalue(options,'ytick')); end
+if exist(options,'ztick'), set(gca,'ZTick',getfieldvalue(options,'ztick')); end
+
+%view 
+if md.dim==3 & ~exist(options,'layer'),
+	view(getfieldvalue(options,'view',3));
+else
+	view(getfieldvalue(options,'view',2));
+end
+
+%latlon
+%Must be done here so that it uses the same xlim and ylim as plot_overlay
+%these are changed by axis that follows
+if exist(options,'latlon')
+	latlonoverlay(options);
+end
+
+%axis
+set(gca,'FontSize',fontsize);
+if exist(options,'axis')
+	eval(['axis ' getfieldvalue(options,'axis')]);
+else
+	if ((md.dim==2) | exist(options,'layer')),
+		axis tight equal;
+	else
+		axis auto tight
+	end
+end
+
+%xlim
+if exist(options,'xlim');
+	xlim(getfieldvalue(options,'xlim'));
+end
+
+%ylim
+if exist(options,'ylim');
+	ylim(getfieldvalue(options,'ylim'));
+end
+
+%zlim
+if exist(options,'zlim');
+	zlim(getfieldvalue(options,'zlim'));
+end
+
+%Basinzoom
+if exist(options,'basin');
+	basinzoom(getfieldvalue(options,'basin'),getfieldvalue(options,'unit',1));
+end
+
+%Caxis
+if exist(options,'caxis'),
+	caxis(getfieldvalue(options,'caxis'));
+end
+
+%shading
+if exist(options,'shading'),
+	shading(getfieldvalue(options,'shading'));
+end
+
+%grid
+if exist(options,'grid'),
+	if strcmpi(getfieldvalue(options,'grid'),'on'),
+		grid on;
+	end
+end
+
+%colormap
+if exist(options,'colormap'),
+	h=colormap(getfieldvalue(options,'colormap'));
+end
+
+%wrapping
+if exist(options,'wrapping'),
+	if ~exist(options,'colormap'),
+		h=jet;
+	end
+	colormap(repmat(h,getfieldvalue(options,'wrapping',1),1));
+end
+
+%colorbar
+if getfieldvalue(options,'colorbar',1)==1,
+	if exist(options,'colorbarcornerposition'),
+		c=colorbar(getfieldvalue(options,'colorbarcornerposition'));
+	else 
+		c=colorbar;
+	end
+	set(c,'FontSize',getfieldvalue(options,'colorbarfontsize',14));
+	if exist(options,'wrapping')
+		lim=get(c,'Ylim');
+		lim=[lim(1) lim(1)+(lim(2)-lim(1))/getfieldvalue(options,'wrapping')];
+		set(c,'Ylim',lim);
+	end
+	if exist(options,'colorbarpos'),
+		set(c,'Position',getfieldvalue(options,'colorbarpos'));
+	end
+	if exist(options,'log'),
+		logvalue=getfieldvalue(options,'log');
+
+		scalestring=get(c,'YTickLabel');
+		scalevalues=get(c,'YTick');
+		scaleminmax=caxis;
+		numvalues=length(scalevalues);
+
+		scalestring=[];
+		for i=1:numvalues,
+			fraction=(scalevalues(i)-scaleminmax(1))/(scaleminmax(2)-scaleminmax(1));
+			scalevalues(i)=round_ice(logvalue^scalevalues(i),2);
+			scalestring=char(scalestring,sprintf('%4.4g',scalevalues(i)));
+		end
+		scalestring=scalestring(2:end,:);
+		set(c,'YTickLabel',scalestring);
+	end
+	if exist(options,'colorbartitle'),
+		backup=gca;
+		axes(c);lab=title(getfieldvalue(options,'colorbartitle'),'Color',getfieldvalue(options,'FontColor','k'));
+		set(lab,'Rotation',getfieldvalue(options,'colorbartitlerotation',0));
+		set(lab,'VerticalAlignment','bottom');
+		axes(backup);
+	end
+	%colorbar OFF
+elseif getfieldvalue(options,'colorbar',1)==0,
+	colorbar('off');
+else
+	%do nothing
+end
+
+%area
+if exist(options,'area'),
+	antzoom(getfieldvalue(options,'area'));
+end
+
+%expdisp
+filename=(getfieldvalue(options,'expdisp'));
+style=(getfieldvalue(options,'expstyle'));
+for i=1:length(getfieldvalue(options,'expdisp')),
+	filenamei=filename{i};
+	stylei=style{i};
+	expdisp(filenamei,gcf,stylei,getfieldvalue(options,'linewidth',1),getfieldvalue(options,'unit',1));
+end
+
+%text (default value is empty, not NaN...)
+if exist(options,'text');
+	textstring=getfieldvalue(options,'text');
+	textweight=getfieldvalue(options,'textweight');
+	textsize=getfieldvalue(options,'textsize');
+	textcolor=getfieldvalue(options,'textcolor');
+	textposition=getfieldvalue(options,'textposition');
+	for i=1:length(getfieldvalue(options,'text'));
+		textstringi=textstring{i};
+		textweighti=textweight{i};
+		textsizei=textsize{i};
+		textcolori=textcolor{i};
+		textpositioni=textposition{i};
+		text(textpositioni(1),textpositioni(2),textstringi,'FontSize',textsizei,'FontWeight',textweighti,'Color',textcolori);
+	end
+end
+
+%north arrow
+if exist(options,'northarrow'),
+	northarrow(getfieldvalue(options,'northarrow'));
+end
+
+%Scale ruler
+if exist(options,'scaleruler'),
+	scaleruler(options);
+end
+
+%streamliness
+if exist(options,'streamlines'),
+	plot_streamlines(md,options);
+end
+
+%contours
+if exist(options,'contourlevels'),
+	plot_contour(md,data,options);
+end
+
+%YTickLabel
+if exist(options,'yticklabel'),
+	set(gca,'YTickLabel',getfieldvalue(options,'YTickLabel'));
+end
+
+%XTickLabel
+if exist(options,'xticklabel'),
+	set(gca,'XTickLabel',getfieldvalue(options,'XTickLabel'));
+end
+
+%xtick
+if exist(options,'xtick'),
+	set(gca,'xtick',getfieldvalue(options,'xtick'));
+end
+
+%ytick
+if exist(options,'ytick'),
+	set(gca,'ytick',getfieldvalue(options,'ytick'));
+end
+
+
+%position of figure
+if exist(options,'figposition'),
+	
+	figposition=getfieldvalue(options,'figposition');
+	if ischar(figposition),
+		if strcmpi(figposition,'larour'),
+			set(gcf,'Position',[1604 4 1594 1177]);
+		elseif strcmpi(figposition,'larour2'),
+			set(gcf,'Position',[756    62   827   504]);
+		elseif strcmpi(figposition,'mathieu'),
+			set(gcf,'Position',[1 1 1580 1150]);
+		else
+			disp('''position'' string not supported yet');
+		end
+	else
+		set(gcf,'Position',figposition);
+	end
+
+end
+
+%axes position
+if exist(options,'axesPosition')
+	set(gca,'Position',getfieldvalue(options,'axesPosition'));
+end
+
+%showregion
+if strcmpi(getfieldvalue(options,'showregion','off'),'on'),
+	%get inset relative position (x,y,width,height)
+	insetpos=getfieldvalue(options,'insetpos',[0.02 0.70 0.18 0.18]);
+	%get current plos position
+	cplotpos=get(gca,'pos');
+	%compute inset position
+	PosInset=[cplotpos(1)+insetpos(1)*cplotpos(3),cplotpos(2)+insetpos(2)*cplotpos(4), insetpos(3)*cplotpos(3), insetpos(4)*cplotpos(4)];
+	axes('pos',PosInset);
+	axis equal off
+	%box off
+	if strcmpi(md.hemisphere,'n') | strcmpi(md.hemisphere,'north'),
+		A=expread([ ISSM_DIR '/../models/Greenland/Exp_Par/DomainOutline.exp']);
+	elseif strcmpi(md.hemisphere,'s') | strcmpi(md.hemisphere,'south'),
+		A=expread([ ISSM_DIR '/../models/Antarctica/Exp_Par/DomainOutline.exp']);
+	else
+		error('applyoptions error message: hemisphere not defined');
+	end
+	Ax=[min(A.x) max(A.x)];
+	Ay=[min(A.y) max(A.y)];
+	%if we are zooming on a basin, don't take the mesh for the boundaries!
+	if exist(options,'basin'),
+		[mdx mdy]=basinzoom(getfieldvalue(options,'basin'));
+	else
+		mdx=[min(md.x) max(md.x)];
+		mdy=[min(md.y) max(md.y)];
+	end
+	line(A.x,A.y,'color','b');
+	patch([Ax(1)  Ax(2)  Ax(2)  Ax(1) Ax(1)],[Ay(1)  Ay(1)  Ay(2)  Ay(2) Ay(1)],[1 1 1],'EdgeColor',[0 0 0],'LineWidth',1,'FaceLighting','none')
+	patch( [mdx(1) mdx(2) mdx(2) mdx(1)],[mdy(1) mdy(1) mdy(2) mdy(2)],ones(4,1),'EdgeColor',[0 0 0],'FaceColor','r','FaceAlpha',0.5)
+	colorbar('off');
+end
+
+
+%flag edges of a partition
+if exist(options,'partitionedges')
+	[xsegments ysegments]=flagedges(md.elements,md.x,md.y,md.part);
+	xsegments=xsegments*getfieldvalue(options,'unit',1);
+	ysegments=ysegments*getfieldvalue(options,'unit',1);
+	color=getfieldvalue(options,'partitionedgescolor','r-');
+	linewidth=getfieldvalue(options,'linewidth',1);
+	hold on;
+	for i=1:length(xsegments),
+		plot(xsegments(i,:),ysegments(i,:),color,'LineWidth',linewidth);
+	end
+end
Index: /issm/trunk/src/m/model/plot/checkplotoptions.m
===================================================================
--- /issm/trunk/src/m/model/plot/checkplotoptions.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/checkplotoptions.m	(revision 5901)
@@ -0,0 +1,209 @@
+function options=checkplotoptions(md,options);
+%PARSE_OPTIONS - build a structure that holds all plot options
+%
+%   Usage:
+%      options=checkplotoptions(md,options);
+%
+%   See also: PLOTMODEL
+
+%units
+if exist(options,'unit'),
+	if strcmpi(getfieldvalue(options,'unit'),'km')
+		options=changefieldvalue(options,'unit',10^-3);
+	end
+end
+
+%density
+if exist(options,'density'),
+	density=getfieldvalue(options,'density');
+	options=changefieldvalue(options,'density',abs(ceil(density)));
+end
+
+%Show section
+if exist(options,'showsection'),
+	if strcmpi(getfieldvalue(options,'showsection'),'on')
+		options=changefieldvalue(options,'showsection',4);
+	end
+end
+
+%iceshelf values
+if exist(options,'iceshelf'),
+	if strcmpi(getfieldvalue(options,'iceshelf'),'none')
+		options=changefieldvalue(options,'iceshelf',0);
+	end
+end
+
+%icesheet values
+if exist(options,'icesheet'),
+	if strcmpi(getfieldvalue(options,'icesheet'),'none')
+		options=changefieldvalue(options,'icesheet',0);
+	end
+end
+
+%water values
+if exist(options,'water'),
+	if strcmpi(getfieldvalue(options,'water'),'none')
+		options=changefieldvalue(options,'water',0);
+	end
+end
+
+%smooth values
+if exist(options,'smooth'),
+	if strcmpi(getfieldvalue(options,'smooth'),'on')
+		options=changefieldvalue(options,'smooth',0);
+	end
+end
+
+%contouronly values
+if exist(options,'contouronly'),
+	if strcmpi(getfieldvalue(options,'contouronly'),'on')
+		options=changefieldvalue(options,'contouronly',1);
+	end
+end
+
+%Colorbar;
+if exist(options,'colorbar'),
+	if strcmpi(getfieldvalue(options,'colorbar'),'on')
+		options=changefieldvalue(options,'colorbar',1);
+	elseif strcmpi(getfieldvalue(options,'colorbar'),'off')
+			options=changefieldvalue(options,'colorbar',0);
+	end
+end
+	
+%text
+if exist(options,'text'),
+	%1: textvalue
+	textvalues=getfieldvalue(options,'text');
+	%ischar if only one expstyle -> create a cell
+	if ischar(textvalues),
+		textvalues={textvalues};
+		numtext=1;
+	elseif iscell(textvalues),
+		numtext=length(textvalues);
+	else
+		error('plot error message: ''text'' option should be either a string or a cell');
+	end
+
+	%2: textweight
+	if exist(options,'textweight'),
+		textweightvalues=getfieldvalue(options,'textweight');
+		%ischar if only one textweight -> create a cell
+		if ischar(textweightvalues),
+			textweightvalues={textweightvalues};
+		elseif ~iscell(textweightvalues);
+			error('plot error message: ''textweight'' option should be either a string or a cell');
+		end
+	else
+		textweightvalues={'n'};
+	end
+	textweightvalues=repmat(textweightvalues,1,numtext); textweightvalues(numtext+1:end)=[];
+	%3: textsize
+	if exist(options,'textsize'),
+		textsizevalues=getfieldvalue(options,'textsize');
+		%ischar if only one textsize -> create a cell
+		if isnumeric(textsizevalues),
+			textsizevalues={textsizevalues};
+		elseif ~iscell(textsizevalues);
+			error('plot error message: ''textsize'' option should be either a number or a cell');
+		end
+	else
+		textsizevalues={14};
+	end
+	textsizevalues=repmat(textsizevalues,1,numtext); textsizevalues(numtext+1:end)=[];
+	%4: textcolor
+	if exist(options,'textcolor'),
+		textcolorvalues=getfieldvalue(options,'textcolor');
+		%ischar if only one textcolor -> create a cell
+		if ischar(textcolorvalues),
+			textcolorvalues={textcolorvalues};
+		elseif ~iscell(textcolorvalues);
+			error('plot error message: ''textcolor'' option should be either a string or a cell');
+		end
+	else
+		textcolorvalues={'k'};
+	end
+	textcolorvalues=repmat(textcolorvalues,1,numtext); textcolorvalues(numtext+1:end)=[];
+	%4: textposition
+	if exist(options,'textposition'),
+		textpositionvalues=getfieldvalue(options,'textposition');
+		%ischar if only one textposition -> create a cell
+		if isnumeric(textpositionvalues),
+			textpositionvalues={textpositionvalues};
+		elseif ~iscell(textpositionvalues);
+			error('plot error message: ''textposition'' option should be either a string or a cell');
+		end
+	else
+		error('plot error message: ''textposition'' option is missing');
+	end
+	options=changefieldvalue(options,'text',textvalues);
+	options=changefieldvalue(options,'textsize',textsizevalues);
+	options=changefieldvalue(options,'textweight',textweightvalues);
+	options=changefieldvalue(options,'textcolor',textcolorvalues);
+	options=changefieldvalue(options,'textposition',textpositionvalues);
+end
+
+%expdisp
+expdispvaluesarray=cell(0,0);
+expstylevaluesarray=cell(0,0);
+expstylevalues=cell(0,0);
+if exist(options,'expstyle'),
+	expstylevalues=getfieldvalue(options,'expstyle');
+	%ischar if only one expstyle -> create a cell
+	if ischar(expstylevalues),
+		expstylevalues={expstylevalues};
+	end
+end
+if exist(options,'expdisp'),
+	expdispvalues=getfieldvalue(options,'expdisp');
+	%ischar if only one expstyle -> create a cell
+	if ischar(expdispvalues),
+		expdispvalues={expdispvalues};
+	end
+	for i=1:length(expdispvalues)
+		expdispvaluesarray{end+1}=expdispvalues{i};
+		if (length(expstylevalues)>=i),
+			expstylevaluesarray{end+1}=expstylevalues{i};
+		else
+			expstylevaluesarray{end+1}='g-';
+		end
+	end
+end
+options=changefieldvalue(options,'expstyle',expstylevaluesarray);
+options=changefieldvalue(options,'expdisp',expdispvaluesarray);
+
+%latlonnumbering
+if exist(options,'latlonclick'),
+	if strcmpi(getfieldvalue(options,'latlonclick'),'on')
+		options=changefieldvalue(options,'latlonclick',1);
+	end
+end
+
+%north arrow
+if exist(options,'northarrow'),
+	if strcmpi(getfieldvalue(options,'northarrow'),'on')
+		%default values
+		Lx=max(md.y)-min(md.y);
+		Ly=max(md.y)-min(md.y);
+		%default values
+		options=changefieldvalue(options,'northarrow',[min(md.x)+1/6*Lx   min(md.y)+5/6*Ly   1/15*Ly   0.25   1/250*Ly]);
+	end
+end
+
+%scale ruler
+if exist(options,'scaleruler'),
+	if strcmpi(getfieldvalue(options,'scaleruler'),'on')
+		%default values
+		Lx=max(md.y)-min(md.y);
+		Ly=max(md.y)-min(md.y);
+		%default values
+		options=changefieldvalue(options,'scaleruler',[min(md.x)+6/8*Lx   min(md.y)+1/10*Ly   10^(ceil(log10(Lx)))/5 floor(Lx/100) 5]);
+	end
+end
+
+%Log scale (LOTS of changes to be performed
+if exist(options,'log'),
+	if exist(options,'caxis')
+		options=changefieldvalue(options,'caxis',log(getfieldvalue(options,'caxis'))/log(getfieldvalue(options,'log')));
+	end
+	options=changefieldvalue(options,'cutoff',log(getfieldvalue(options,'cutoff',1.5))/log(getfieldvalue(options,'log')));
+end
Index: /issm/trunk/src/m/model/plot/imagescnan.m
===================================================================
--- /issm/trunk/src/m/model/plot/imagescnan.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/imagescnan.m	(revision 5901)
@@ -0,0 +1,303 @@
+function [h,hcb] = imagescnan(x,y,U,varargin)
+%IMAGESCNAN Scale data and display as image with uncolored NaNs.
+%
+%   Syntax
+%               imagescnan(x,y,U)
+%               imagescnan(x,y,U,...,colormask)
+%               imagescnan(x,y,U,...,color)
+%               imagescnan(x,y,U,...,cbfit_opt)
+%           h = imagescnan(...);
+%     [h,hcb] = imagescnan(...,cbfit_opt);
+%
+%   Input:
+%     x          - X-axis vector data. Optional, i.e., can be empty.
+%                  Default: 1:n (rows index).
+%     y          - Y-axis vector data. Optional, i.e., can be empty.
+%                  Default: 1:m (column index).
+%     U          - Matrix [m x n] data or an RGB image [m x n x 3] (with/
+%                  without NaNs). 
+%     colormask  - Logical matrix indicating the U elements to be
+%                  uncolored, if is empty then ISNAN(U) is used. Or it can
+%                  be a single value which will be uncolored.
+%                  Default: ~isfinite(U) (NaNs and Infs elements uncolored)
+%     color      - A vector with 3 elements specifying the [R G B] color
+%                  for the NaNs color. It can be specified by the known
+%                  char colors: 'k', etcerera. Optional.  
+%                  Default: get(gca,'color') (axes background color)
+%     cbfit_opt  - Cell array with the options to call COLORBARFIT.
+%                  Default: COLORBARFIT function is not used by default.
+%
+%   Output:
+%     h   - Image handle. Optional
+%     hcb - Colorbar handle. Optional
+%
+%   Description:
+%      This function draws a matrix data as an image with uncolored NaN's
+%      elements using IMAGESC. The difference between IMAGESC and the
+%      PCOLOR, MESH or SURF function is that EVERY element is colored and
+%      no one is interpolated, besides, the pixels are centered with the
+%      axis value, although it is a flat image.
+%
+%      The color mask is added because IMAGESC do not work with NaN's, in
+%      fact it colors them with the lower value of the current colormap.
+%      
+%      The cbfit_opt is include in order to be able to define a diferent
+%      color map with the COLORBARFIT function which can be found at:
+%           http://www.mathworks.com/matlabcentral/fileexchange/.
+%      If this function is not found, a normal COLORBAR is generated.
+%
+%      The data and the colorbar are scaled with the current colormap, so,
+%      the use of COLORMAP after this function doesn't affects the
+%      generated image and colorbar! Therefore, COLORMAP and CAXIS should
+%      be used before this function.
+%
+%      Notes: * The inputs arguments for the COLORBARFIT function are 3
+%               plus the normal COLORBAR function options, for this reason,
+%               if the former is not found, the latter is used ignoring
+%               these first 3 options. Anyway, to generate a colorbar, at
+%               least an empty cell is needed for cbfit_opt = {[]}.
+%   
+%   Examples:
+%
+%      % Compares with normal IMAGESC:
+%       N = 100;
+%       PNaNs = 0.10;
+%       X = peaks(N);
+%       X(round(1 + (N^2-1).*rand(N^2*PNaNs,1))) = NaN;
+%       subplot(221), imagesc(X)
+%        title('With IMAGESC: ugly NaNs')
+%       subplot(222), imagescnan([],[],X) 
+%        title('With IMAGESCNAN: uncolored NaNs')
+%
+%      % Compares with SPY:
+%       subplot(223), spy(isnan(X))
+%        title('SPY NaNs')
+%       subplot(224), imagescnan([],[],isnan(X),0), axis equal tight
+%        title('No-NaNs with IMAGESCNAN')
+%
+%   See also IMAGE, IMAGESC, COLORBAR, IMREAD, IMWRITE and COLORBARFIT by
+%   Carlos Vargas. 
+
+%   Copyright 2008 Carlos Adrian Vargas Aguilera
+%   $Revision: 1.1 $  $Date: 2009/04/03 22:56:05 $
+
+%   Written by
+%   M.S. Carlos Adrian Vargas Aguilera
+%   Physical Oceanography PhD candidate
+%   CICESE 
+%   Mexico, 2008
+%   nubeobscura@hotmail.com
+%
+%   Download from:
+%   http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objec
+%   tType=author&objectId=1093874
+
+%   1.0     Released (30/06/2008)
+%   1.1     Fixed bug when CAXIS used.
+%   1.2     Colorbar freezed colormap.
+%   1.3     Fixed bug in color vector input (Found by Greg King) and now
+%           accets RGB image as input.
+
+%% INPUTS:
+
+% Error checking:
+% Note: At least 3 inputs and no more than 6:
+if nargin<3 || nargin>6
+ error('Imagescnan:IncorrectInputNumber',...
+       'Input arguments must be at least 3 and less than 7.')
+end
+
+% Check the x,y,U:
+% Note: x,y should be the axes data.
+m = size(U);
+if numel(m)>3
+ error('Imagescnan:IncorrectInputSize',...
+       'Input image must be a matrix or an RGB image.')
+else
+ if isempty(x) || numel(x)~=m(2)
+  %warning('Imagescnan:IncorrectInputSize',...
+  %        'Index column axis has been used.')
+  x = 1:m(2); 
+ end
+ if isempty(y) || numel(y)~=m(1)
+  %warning('Imagescnan:IncorrectInputSize',...
+  %        'Index row axis has been used.')
+  y = 1:m(1); 
+ end
+end
+
+% Get color limits:
+% Note: If you would like to use specific color limits, use CAXIS before
+%       this function.
+switch get(gca,'CLimMode')
+ case 'manual'
+  clim = caxis;
+ otherwise
+  clim = [min(U(:)) max(U(:))];
+end
+
+% Parse inputs and defaults:
+% Note: * Mask color will be the not-finite elements plus the elements
+%         indicated by the user.
+%       * Default colormask is the current axes background.
+%       * Default currentmap is current figure colormap (probably JET).
+colormask = ~isfinite(U);
+color_nan = get(gca,'color');
+color_map = get(gcf,'colormap'); 
+cbfit_opt = [];
+ycolorbarfit = (exist('colorbarfit','file')==2);
+if nargin>3
+ while ~isempty(varargin)
+  if     iscell(varargin{1})
+   if length(varargin{1})<3
+    error('Imagescnan:IncorrectInputType',...
+     'Options for COLORBARFIT must be at least 3, although empty.')
+   end
+   caxis(clim)
+   cbfit_opt = varargin{1};
+   if ycolorbarfit
+    colorbarfit(cbfit_opt{:})
+    color_map = get(gcf,'colormap');
+   else
+    % warning('Imagescnan:ColorBarFitNotFound',...
+    %  'COLORBARFIT function not found, used default COLORBAR.') 
+   end
+   varargin(1) = [];
+  elseif ischar(varargin{1})
+   switch varargin{1}
+    case 'y', color_nan = [1 1 0];
+    case 'm', color_nan = [1 0 0];
+    case 'c', color_nan = [0 1 1];
+    case 'r', color_nan = [1 0 0];
+    case 'g', color_nan = [0 1 0];
+    case 'b', color_nan = [0 0 1];
+    case 'w', color_nan = [1 1 1];
+    case 'k', color_nan = [0 0 0];
+   otherwise
+   error('Imagescnan:InvalidColor',...
+    'Color char must be one of: ''ymcrgbwk''.')
+   end
+   varargin(1) = [];
+  elseif islogical(varargin{1})
+   if numel(varargin{1})~=numel(U)
+    error('Imagescnan:InvalidMask',...
+     'The logical mask must have the same elements as the matrix.')
+   end
+   colormask = varargin{1} | colormask;
+   varargin(1) = [];
+  elseif length(varargin{1})==3
+   if (max(varargin{1})>1) || (min(varargin{1})<0) % Fixed BUG 2008/07/11
+    error('Imagescnan:InvalidColor',...
+     'The color must be on the range of [0 1].')
+   end
+   color_nan = varargin{1};
+   varargin(1) = [];
+  elseif length(varargin{1})==1
+   colormask = (U==varargin{1}) | colormask;
+   varargin(1) = [];
+  else
+   error('Imagescnan:IncorrectInputType',...
+    'Incorrect optional(s) argument(s).')
+  end
+ end
+end
+
+
+%% MAIN:
+
+% Matrix data to RGB:
+if numel(m)==2
+
+ % Sets to double data:
+ if ~isfloat(U)
+  U = double(U);
+ end
+
+ % Normalizes and rounds data to range [0 N]:
+ N = size(color_map,1);
+ U = (U - clim(1))/diff(clim);          % Fixed bug when CAXIS used
+ U = U*N;
+ if N<=256
+  U = uint8(U);
+ else
+  U = uint16(U);
+ end
+
+ % Scales data with colormap:
+ U = ind2rgb(U,color_map);              % 2D to 3D RGB values [0 1]
+else
+ % Already is an RGB image, so do nothing.
+end
+
+ % Set mask color to color_nan:
+ mn = prod(m(1:2));
+ ind = find(colormask);
+ U(ind)      = color_nan(1); % Red color
+ U(ind+mn)   = color_nan(2); % Green color
+ U(ind+mn*2) = color_nan(3); % Blue color
+
+ % Draws the RGB image:
+ h = imagesc(x,y,U,clim);
+
+%% OUTPUTS:
+
+% Calls to colorbarfit and freezes his colormap:
+if ~isempty(cbfit_opt)
+ % Creates a temporary colorbar:
+ if ycolorbarfit
+  hcb   = colorbarfit(cbfit_opt{:});
+ else
+  Nopt = min([3 length(cbfit_opt)]);
+  cbfit_opt(1:Nopt) = [];
+  hcb   = colorbar(cbfit_opt{:});
+ end
+ % Save image position:
+ ha    = gca; position = get(ha,'Position'); 
+ % Gets colorbar axes properties:
+ ghcb  = get(hcb);
+ CData = ind2rgb(get(ghcb.Children,'CData'),color_map);
+ XData = get(ghcb.Children,'XData');
+ YData = get(ghcb.Children,'YData');
+ % Move ticks because IMAGESC draws them like centered pixels:
+ XTick = ghcb.XTick;
+ YTick = ghcb.YTick;
+ if ~isempty(XTick)
+  XTick = XTick(1:end-1) + diff(XTick(1:2))/2;
+ end
+ if ~isempty(YTick)
+  YTick = YTick(1:end-1) + diff(YTick(1:2))/2;
+ end
+ % Deletes the colorbar:
+ delete(hcb)            
+ % Generates other colorbar:
+ hcb = axes('Position',ghcb.Position);
+ hcbim = imagesc(XTick,YTick,CData,'Parent',hcb); axis tight
+ set(hcbim,...
+  'HitTest','off',...
+  'Interruptible','off',...
+  'SelectionHighlight','off',...
+  'Tag','TMW_COLORBAR',...
+  'XData',XData,...
+  'YData',YData)
+ set(hcb,...
+  'XAxisLocation',ghcb.XAxisLocation,...
+  'YAxisLocation',ghcb.YAxisLocation,...
+  'XLim',ghcb.XLim,...
+  'YLim',ghcb.YLim,...
+  'XDir',ghcb.XDir,...
+  'YDir',ghcb.YDir,...
+  'XTick',ghcb.XTick,...
+  'YTick',ghcb.YTick,...
+  'XTickLabel',ghcb.XTickLabel,...
+  'YTickLabel',ghcb.YTickLabel,...
+  'ButtonDownFcn',@resetCurrentAxes,...
+  'Interruptible','off',...
+  'Tag','Colorbar')
+ % Returns the image position:
+ axes(ha), set(ha,'Position',position)
+end
+
+% Sets output:
+if ~nargout
+ clear h
+end
Index: /issm/trunk/src/m/model/plot/latlonoverlay.m
===================================================================
--- /issm/trunk/src/m/model/plot/latlonoverlay.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/latlonoverlay.m	(revision 5901)
@@ -0,0 +1,167 @@
+function latlonoverlay(options)
+%LATLONOVERLAY - overlay latitude and longitude lines on current figure
+%
+%   latstep,lonstep, in latitude and longitude degreees, between two latitudinal, longitudinal profiles.
+%   color: [1 1 1] for example
+%   resolution: profile resolution ( in lat,lon degrees) 
+%   gap: gap (in meters) to plug lat,lon degree numbers;
+%
+%   Usage:
+%      latlonoverlay(options)
+
+%get options
+latlon=getfieldvalue(options,'latlon');
+numbering=getfieldvalue(options,'latlonnumbering');
+latlonclick=getfieldvalue(options,'latlonclick',0);
+fontsize=getfieldvalue(options,'fontsize',16);
+
+%recover arguments (set default parameters if needed)
+%1: latlon
+if ~iscell(latlon),
+	if ischar(latlon) & strcmpi(latlon,'on'),
+		latstep=3;
+		lonstep=3;
+		resolution=0.1;
+		color=[1 1 1];
+	else
+		return;
+	end
+else
+	if length(latlon)<2
+		error('latlonoverlay error message: at least 2 arguments are required, or use ''on'' option.');
+	end
+	if length(latlon)==2,
+		latstep=latlon{1};
+		lonstep=latlon{2};
+		resolution=0.1;
+		color=[1 1 1];
+	elseif length(latlon)==3,
+		latstep=latlon{1};
+		lonstep=latlon{2};
+		resolution=latlon{3};
+		color=[1 1 1];
+	else
+		latstep=latlon{1};
+		lonstep=latlon{2};
+		resolution=latlon{3};
+		color=latlon{4};
+	end
+end
+
+%2: numbering
+if ~iscell(numbering) & isnan(numbering),
+	numbering=0;
+else
+	if ~iscell(numbering),
+		if strcmpi(char(numbering),'on'),
+			latgap=2;
+			longap=2;
+			colornumber=color;
+			latangle=0;
+			lonangle=0;
+			numbering=1;
+		else
+			numbering=0;
+		end
+	else
+		latgap=numbering{1};
+		longap=numbering{2};
+		colornumber=numbering{3};
+		latangle=numbering{4};
+		lonangle=numbering{5};
+		numbering=1;
+	end
+end
+
+%Find lat and lon that fit within the bounds of our image.
+lat=-90:resolution:0;
+lon=0:resolution:360;
+
+xlimits=xlim;
+ylimits=ylim;
+
+for i=1:length(lon),
+	if(rem(lon(i),lonstep)==0)
+		latitudes=lat';
+		longitudes=lon(i)*ones(length(latitudes),1);
+		[x,y]=mapll(latitudes,longitudes,'s');
+		pos=find(x<=xlimits(2) & x>=xlimits(1) & y<=ylimits(2) & y>=ylimits(1));
+		if length(pos)<=1,
+			continue;
+		end
+		x=x(pos);y=y(pos);
+
+		l=line(x,y,'Color',color);
+		if numbering,
+			if latlonclick
+				disp(['Specifiy where to put number for longitude ' num2str(lon(i))]);
+				[xcorner,ycorner]=ginput(1);
+
+				%Find nearest point on this profile corresponding to (xcorner,ycorner):
+				ind=find_point(x,y,xcorner,ycorner); xcorner=x(ind); ycorner=y(ind);
+			else
+				ind=round(9*length(x)/10); xcorner=x(ind); ycorner=y(ind);
+			end
+			if length(x(1:ind))>10,
+				xcorner2=x(ind-10); ycorner2=y(ind-10);
+			else
+				xcorner2=x(ind-1); ycorner2=y(ind-1);
+			end
+			angle=mod((180)/pi*atan2((ycorner2-ycorner),(xcorner2-xcorner))+lonangle,360);
+			
+			if (xcorner>xlimits(1) & xcorner<xlimits(2) & ycorner>ylimits(1) & ycorner<ylimits(2)),
+				th=text(xcorner,ycorner,[num2str(lon(i)) '^{\circ}']);set(th,'Color',colornumber,'Rotation',angle,'FontSize',fontsize,'HorizontalAlignment','center','VerticalAlignment','middle');
+				
+				%erase line and redraw it in two parts, to leave space for latitude number
+				delete(l);
+				line(x(1:ind-longap),y(1:ind-longap),'Color',color);hold on;
+				line(x(ind+longap:end),y(ind+longap:end),'Color',color);
+			end
+
+		end
+	end
+end
+
+for i=1:length(lat),
+	if(rem(lat(i),latstep)==0)
+		longitudes=lon';
+		latitudes=lat(i)*ones(length(longitudes),1);
+		[x,y]=mapll(latitudes,longitudes,'s');
+		pos=find(x<=xlimits(2) & x>=xlimits(1) & y<=ylimits(2) & y>=ylimits(1));
+		if length(pos)<=1,
+			continue;
+		end
+		x=x(pos);y=y(pos);
+
+		l=line(x,y,'Color',color);
+		
+		if numbering,
+			if latlonclick
+				disp(['Specifiy where to put number for latitude ' num2str(lat(i))]);
+				[xcorner,ycorner]=ginput(1);
+
+				%Find nearest point on this profile corresponding to (xcorner,ycorner):
+				ind=find_point(x,y,xcorner,ycorner); xcorner=x(ind); ycorner=y(ind);
+			else
+				ind=round(9*length(x)/10); xcorner=x(ind); ycorner=y(ind);
+			end
+			if length(x(1:ind))>10,
+				xcorner2=x(ind-10); ycorner2=y(ind-10);
+			else
+				xcorner2=x(ind-1); ycorner2=y(ind-1);
+			end
+			angle=mod((180)/pi*atan2((ycorner2-ycorner),(xcorner2-xcorner))+lonangle,360);
+			
+			if (xcorner>xlimits(1) & xcorner<xlimits(2) & ycorner>ylimits(1) & ycorner<ylimits(2)),
+				th=text(xcorner,ycorner,[num2str(lat(i)) '^{\circ}']);set(th,'Color',colornumber,'Rotation',angle,'FontSize',fontsize,'HorizontalAlignment','center','VerticalAlignment','middle');
+				
+				%erase line and redraw it in two parts, to leave space for latitude number
+				delete(l);
+				line(x(1:ind-latgap),y(1:ind-latgap),'Color',color);hold on;
+				line(x(ind+latgap:end),y(ind+latgap:end),'Color',color);
+			end
+
+		end
+
+	end
+end
Index: /issm/trunk/src/m/model/plot/northarrow.m
===================================================================
--- /issm/trunk/src/m/model/plot/northarrow.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/northarrow.m	(revision 5901)
@@ -0,0 +1,73 @@
+function northarrow(structure)
+%NORTHARROW - overlay an arrow pointing north on the current plot
+%
+%   Usage:
+%      northarrow(structure)
+
+%Go through structure and fill missing arguments
+if length(structure)<3
+	error('plotmodel error message: the position or the length of the North arrow is missing');
+elseif length(structure)==3
+	structure(4)=0.5; %default ratio headarrow/length
+	structure(5)=structure(3)/10; %default width =length/10
+elseif length(structure)==4
+	structure(5)=structure(3)/10; %default width =length/10
+elseif length(structure)>5
+	error('plotmodel error message: to many input arguments for northarrow: [x0 y0 length [ratio [width]]]');
+end
+
+%retrieve north arrow parameters
+x0=structure(1);
+y0=structure(2);
+lengtharrow=structure(3);
+ratio=structure(4);
+width=structure(5);
+
+%Figure out angle to point towards north
+ang=atan2(y0,x0);
+
+%Build the two points Ap and Bp
+x=zeros(2,1);
+y=zeros(2,1);
+x(1)=x0;
+y(1)=y0;
+
+x(2)=x(1)+lengtharrow*cos(ang);
+y(2)=y(1)+lengtharrow*sin(ang);
+
+Ap=[x(1)
+   y(1)];
+Bp=[x(2)
+   y(2)];
+
+%Build arrowhead first
+ang2=150*2*pi/360;
+rotation=[cos(ang2), sin(ang2); -sin(ang2), cos(ang2)];
+
+E=ratio*rotation*(Bp-Ap)+Bp;
+F=Bp;
+G=ratio*rotation'*(Bp-Ap)+Bp;
+H=Bp/4+E*3/8+G*3/8;
+
+%Build rectangle
+u=Bp-Ap;
+alpha=atan2(u(2),u(1));
+
+A=Ap-[-width/2*sin(alpha)
+   width/2*cos(alpha)];
+ B=H-[-width/2*sin(alpha)
+   width/2*cos(alpha)];
+C=H+[-width/2*sin(alpha)
+   width/2*cos(alpha)];
+D=Ap+[-width/2*sin(alpha)
+   width/2*cos(alpha)];
+
+%Plot arrow
+hold on
+p1=patch([A(1) B(1) C(1) D(1)],[A(2) B(2) C(2) D(2)],'Black');
+p2=patch([E(1) F(1) G(1) H(1)],[E(2) F(2) G(2) H(2)],'Black');
+
+%Text North
+xN=max([A(1) D(1) E(1) F(1) G(1)])+ratio/3*lengtharrow;
+yN=mean([A(2) F(2) H(2)]);
+text(xN,yN,'North','FontSize',16,'FontWeight','b');
Index: /issm/trunk/src/m/model/plot/plot_BC.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_BC.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_BC.m	(revision 5901)
@@ -0,0 +1,24 @@
+function plot_BC(md,options,width,i,data);
+
+%plot neuman
+plot_pressureload(md,options,width,i,data)
+
+hold on
+
+%plot dirichlets
+h1=plot(md.x(find(md.spcvelocity(:,1))),md.y(find(md.spcvelocity(:,1))),'ro','MarkerSize',14,'MarkerFaceColor','r');
+h2=plot(md.x(find(md.spcvelocity(:,2))),md.y(find(md.spcvelocity(:,2))),'bo','MarkerSize',10,'MarkerFaceColor','b');
+h3=plot(md.x(find(md.spcvelocity(:,3))),md.y(find(md.spcvelocity(:,3))),'yo','MarkerSize',6 ,'MarkerFaceColor','y');
+
+%update legend
+[legend_h,object_h,plot_h,text_strings]=legend();
+legend('off');
+text_strings{end+1}='vx boundary';
+text_strings{end+1}='vy dirichlet';
+if h3, text_strings{end+1}='vz dirichlet'; end
+plot_h(end+1)=h1;
+plot_h(end+1)=h2;
+if h3, plot_h(end+1)=h3; end
+legend(plot_h,text_strings,'location','NorthEast')
+
+hold off
Index: /issm/trunk/src/m/model/plot/plot_basaldrag.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_basaldrag.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_basaldrag.m	(revision 5901)
@@ -0,0 +1,53 @@
+function plot_basaldrag(md,options,width,i,type);
+
+%PLOT_BASALDRAG - plot basal drag
+%
+%   Usage:
+%      plot_basaldrag(md,options,width,i,type);
+%
+%   See also: PLOTMODEL
+
+%check layer
+if md.dim==3,
+	if getfieldvalue(options,'layer',1)~=1;
+		disp('plot_basaldrag warning: basal drag is displayed in the lower layer')
+		changefieldvalue(options,'layer',1);
+	end
+end
+
+%compute exponents
+s=averaging(md,1./md.drag_p,0);
+r=averaging(md,md.drag_p./md.drag_q,0);
+
+%compute horizontal velocity
+if strcmpi(type,'basal_drag')
+	ub=sqrt(md.vx.^2+md.vy.^2)/md.yts;
+elseif strcmpi(type,'basal_dragx')
+	ub=md.vx/md.yts;
+elseif strcmpi(type,'basal_dragy')
+	ub=md.vy/md.yts;
+end
+
+%compute basal drag
+drag=(md.g*(md.rho_ice*md.thickness+md.rho_water*md.bed)).^r.*(md.drag_coefficient).^2.*ub.^s/1000;
+
+%Figure out if this is a Section plot
+if exist(options,'sectionvalue')
+	plot_section(md,drag,options,width,i);
+	return;
+else
+
+	%process data and model
+	[x y z elements is2d]=processmesh(md,[],options);
+	[basal_drag datatype]=processdata(md,drag,options);
+
+	%plot basaldrag
+	subplot(width,width,i); 
+	plot_unit(x,y,z,elements,basal_drag,is2d,datatype,options);
+
+	%apply options
+	options=addfielddefault(options,'title','Basal drag [kPa]');
+	options=addfielddefault(options,'view',2);
+	applyoptions(md,basal_drag,options);
+
+end
Index: /issm/trunk/src/m/model/plot/plot_boundaries.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_boundaries.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_boundaries.m	(revision 5901)
@@ -0,0 +1,39 @@
+function plot_boundaries(md,options,width,i);
+%PLOT_BOUNDARIES - plot mesh boundaries
+%
+%   Usage:
+%      plot_boundaries(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+subplot(width,width,i); 
+
+%process data and model
+if getfieldvalue(options,'layer',0)
+	options=removefield(options,'layer',1);
+end
+[x y z elements is2d]=processmesh(md,[],options);
+
+for i=1:size(md.segments,1),
+	plot(x(md.segments(i,1:2)),y(md.segments(i,1:2)),'k.-');hold on;
+end
+
+%plot rifts if present: 
+if isstruct(md.rifts),
+	for i=1:size(md.rifts,1),
+		segments=md.rifts(i).segments;
+		for j=1:size(segments,1),
+			plot(x(segments(j,1:2)),y(segments(j,1:2)),'r.-');
+		end
+		text(x(segments(floor(size(segments,1)/4),1)),y(segments(floor(size(segments,1)/4),1)),['Rift #' num2str(i)]);
+		%point out the tips
+		plot(x(md.rifts(i).tips(1)),y(md.rifts(i).tips(1)),'b*');
+		plot(x(md.rifts(i).tips(2)),y(md.rifts(i).tips(2)),'b*');
+	end
+end
+
+%apply options
+options=addfielddefault(options,'title','Mesh boundaries');
+options=addfielddefault(options,'colorbar',0);
+options=addfielddefault(options,'view',2);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_contour.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_contour.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_contour.m	(revision 5901)
@@ -0,0 +1,243 @@
+function plot_contour(md,datain,options);
+%PLOT_CONTOUR - plot contours of a given field
+%
+%   Usage:
+%      plot_contour(md,data,options);
+%
+%   See also: PLOTMODEL
+
+%process data and model
+[x y z index is2d]=processmesh(md,[],options);
+[data datatype]=processdata(md,datain,options);
+
+%check is2d
+if ~is2d,
+	error('plot_contour error message: contour not supported for 3d meshes, project on a layer');
+end
+
+%first, process data: must be on grids
+if datatype==1,
+	%elements -> take average
+	data=averaging(md,data,0);
+elseif datatype==2,
+	%nodes -> do nothing
+elseif datatype==3,
+	%quiver -> take norm
+	data=sqrt(sum(datain.*datain,2));
+else
+	error('datatype not supported yet');
+end
+
+%prepare colors
+if exist(options,'contouronly')
+	%remove the previous plots
+	cla
+end
+color=getfieldvalue(options,'contourcolor','y');
+
+%get contours levels
+contourlevels=getfieldvalue(options,'contourlevels');
+if isnumeric(contourlevels),
+	levels=round_ice(linspace(max(data),min(data),contourlevels),2);
+else
+	levels=[];
+	for i=1:length(contourlevels)
+		levels(end+1)=contourlevels{i};
+	end
+	levels=sort(unique(levels),'descend');
+end
+numlevels=length(levels);
+
+%initialization of some variables
+numberofelements=size(index,1);
+elementslist=1:numberofelements;
+c=[];
+h=[];
+
+%get unique edges in mesh
+%1: list of edges
+edges=[index(:,[1,2]); index(:,[2,3]); index(:,[3,1])];
+%2: find unique edges
+[edges,I,J]=unique(sort(edges,2),'rows');
+%3: unique edge numbers
+vec=J;
+%4: unique edges numbers in each triangle (2 triangles sharing the same edge will have
+%   the same edge number)
+edges_tria=[vec(elementslist), vec(elementslist+numberofelements), vec(elementslist+2*numberofelements)];
+
+%segments [grids1 gruids2]
+Seg1=index(:,[1 2]);
+Seg2=index(:,[2 3]);
+Seg3=index(:,[3 1]);
+
+%segment numbers [1;4;6;...]
+Seg1_num=edges_tria(:,1);
+Seg2_num=edges_tria(:,2);
+Seg3_num=edges_tria(:,3);
+
+%value of data on each tips of the segments
+Data1=data(Seg1);
+Data2=data(Seg2);
+Data3=data(Seg3);
+
+%get the ranges for each segment
+Range1=sort(Data1,2);
+Range2=sort(Data2,2);
+Range3=sort(Data3,2);
+
+for i=1:numlevels
+
+	level=levels(i);
+
+	%find the segments that contain this value
+	pos1=(Range1(:,1)<level & Range1(:,2)>level);
+	pos2=(Range2(:,1)<level & Range2(:,2)>level);
+	pos3=(Range3(:,1)<level & Range3(:,2)>level);
+
+	%get elements
+	poselem12=(pos1 & pos2);
+	poselem13=(pos1 & pos3);
+	poselem23=(pos2 & pos3);
+	poselem=find(poselem12 | poselem13 | poselem23);
+	numelems=length(poselem);
+
+	%if no element has been flagged, skip to the next level
+	if numelems==0,
+		continue,
+	end
+
+	%go through the elements and build the coordinates for each segment (1 by element)
+	x1=zeros(numelems,1);
+	x2=zeros(numelems,1);
+	y1=zeros(numelems,1);
+	y2=zeros(numelems,1);
+	edge_l=zeros(numelems,2);
+
+	for j=1:numelems,
+
+		weight1=(level-Data1(poselem(j),1))/(Data1(poselem(j),2)-Data1(poselem(j),1));
+		weight2=(level-Data2(poselem(j),1))/(Data2(poselem(j),2)-Data2(poselem(j),1));
+		weight3=(level-Data3(poselem(j),1))/(Data3(poselem(j),2)-Data3(poselem(j),1));
+
+		if poselem12(poselem(j));
+
+			x1(j)=x(Seg1(poselem(j),1))+weight1*(x(Seg1(poselem(j),2))-x(Seg1(poselem(j),1)));
+			x2(j)=x(Seg2(poselem(j),1))+weight2*(x(Seg2(poselem(j),2))-x(Seg2(poselem(j),1)));
+			y1(j)=y(Seg1(poselem(j),1))+weight1*(y(Seg1(poselem(j),2))-y(Seg1(poselem(j),1)));
+			y2(j)=y(Seg2(poselem(j),1))+weight2*(y(Seg2(poselem(j),2))-y(Seg2(poselem(j),1)));
+			edge_l(j,1)=Seg1_num(poselem(j));
+			edge_l(j,2)=Seg2_num(poselem(j));
+
+		elseif poselem13(poselem(j)),
+
+			x1(j)=x(Seg1(poselem(j),1))+weight1*(x(Seg1(poselem(j),2))-x(Seg1(poselem(j),1)));
+			x2(j)=x(Seg3(poselem(j),1))+weight3*(x(Seg3(poselem(j),2))-x(Seg3(poselem(j),1)));
+			y1(j)=y(Seg1(poselem(j),1))+weight1*(y(Seg1(poselem(j),2))-y(Seg1(poselem(j),1)));
+			y2(j)=y(Seg3(poselem(j),1))+weight3*(y(Seg3(poselem(j),2))-y(Seg3(poselem(j),1)));
+			edge_l(j,1)=Seg1_num(poselem(j));
+			edge_l(j,2)=Seg3_num(poselem(j));
+
+		elseif poselem23(poselem(j)),
+
+			x1(j)=x(Seg2(poselem(j),1))+weight2*(x(Seg2(poselem(j),2))-x(Seg2(poselem(j),1)));
+			x2(j)=x(Seg3(poselem(j),1))+weight3*(x(Seg3(poselem(j),2))-x(Seg3(poselem(j),1)));
+			y1(j)=y(Seg2(poselem(j),1))+weight2*(y(Seg2(poselem(j),2))-y(Seg2(poselem(j),1)));
+			y2(j)=y(Seg3(poselem(j),1))+weight3*(y(Seg3(poselem(j),2))-y(Seg3(poselem(j),1)));
+			edge_l(j,1)=Seg2_num(poselem(j));
+			edge_l(j,2)=Seg3_num(poselem(j));
+		else
+			%it shoud not go here
+		end
+	end
+
+	%now that we have the segments, we must try to connect them...
+
+	%loop over the subcontours
+	while ~isempty(edge_l),
+
+		%take the right edge of the second segment and connect it to the next segments if any
+		e1=edge_l(1,1);   e2=edge_l(1,2);
+		xc=[x1(1);x2(1)]; yc=[y1(1);y2(1)];
+
+		%erase the lines corresponding to this edge
+		edge_l(1,:)=[];
+		x1(1)=[]; x2(1)=[];
+		y1(1)=[]; y2(1)=[];
+
+		[ro1,co1]=find(edge_l==e1);
+
+		while ~isempty(ro1)
+
+			if co1==1,
+				xc=[x2(ro1);xc]; yc=[y2(ro1);yc];
+
+				%next edge:
+				e1=edge_l(ro1,2);
+
+			else
+				xc=[x1(ro1);xc]; yc=[y1(ro1);yc];
+
+				%next edge:
+				e1=edge_l(ro1,1);
+			end
+
+			%erase the lines of this
+			edge_l(ro1,:)=[];
+			x1(ro1)=[]; x2(ro1)=[];
+			y1(ro1)=[]; y2(ro1)=[];
+
+			%next connection
+			[ro1,co1]=find(edge_l==e1);
+		end
+
+		%same thing the other way (to the right)
+		[ro2,co2]=find(edge_l==e2);
+
+		while ~isempty(ro2)
+
+			if co2==1,
+				xc=[xc;x2(ro2)]; yc=[yc;y2(ro2)];
+
+				%next edge:
+				e2=edge_l(ro2,2);
+			else
+				xc=[xc;x1(ro2)]; yc=[yc;y1(ro2)];
+
+				%next edge:
+				e2=edge_l(ro2,1);
+			end
+
+			%erase the lines of this
+			edge_l(ro2,:)=[];
+			x1(ro2)=[]; x2(ro2)=[];
+			y1(ro2)=[]; y2(ro2)=[];
+
+			%next connection
+			[ro2,co2]=find(edge_l==e2);
+		end
+
+		%we now have one subcontour ready to be plotted
+		zc=level*ones(length(xc)+1,1);
+		if getfieldvalue(options,'contouronly',0),
+			h=[h;patch('Xdata',[xc;NaN],'Ydata',[yc;NaN],'Zdata',zc,'Cdata',zc,'facecolor','none','edgecolor','flat')];
+			hold on      
+		else
+			h=[h;patch('Xdata',[xc;NaN],'Ydata',[yc;NaN],'facecolor','none','edgecolor',color)];
+			hold on
+		end
+
+		% Update the CS data structure as per "contours.m"
+		% so that clabel works
+		c = horzcat(c,[level, xc'; length(xc), yc']);
+
+	end
+end
+
+%labels?
+if (~strcmpi(getfieldvalue(options,'contourticks','on'),'off') & ~isempty(c) & ~isempty(h))
+	if exist(options,'contouronly')
+		clabel(c,h);
+	else
+		clabel(c,h,'color',color,'FontSize',14);
+	end
+end
Index: /issm/trunk/src/m/model/plot/plot_drivingstress.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_drivingstress.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_drivingstress.m	(revision 5901)
@@ -0,0 +1,24 @@
+function plot_drivingstress(md,options,width,i);
+%PLOT_DRIVINGSTRESS - plot driving stress
+%
+%   Usage:
+%      plot_drivingstress(md,options,width,i);
+%
+%   See also: PLOTMODEL, PLOT_UNIT, PLOT_MANAGER
+
+%get driving stress
+[sx sy s]=drivingstress(md);
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+[dstress datatype]=processdata(md,s,options);
+dstress=dstress/1000;
+
+%plot mesh quivervel
+subplot(width,width,i); 
+plot_unit(x,y,z,elements,dstress,is2d,datatype,options)
+
+%apply options
+options=addfielddefault(options,'title','Driving stress [kPa]');
+options=addfielddefault(options,'view',2);
+applyoptions(md,dstress,options);
Index: /issm/trunk/src/m/model/plot/plot_edges.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_edges.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_edges.m	(revision 5901)
@@ -0,0 +1,34 @@
+function plot_edges(md,options,width,i,datai);
+%PLOT_SEGMENTS - plot edges, with different colors according to segment markers.
+%
+%   Usage:
+%      plot_edges(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%plot mesh boundaries
+subplot(width,width,i); 
+
+%process mesh and data
+[x y z elements is2d]=processmesh(md,[],options);
+edges=md.edges;
+if isnan(edges)
+	error('edges in NaN')
+end
+
+if (md.dim==2),
+	%plot mesh
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); 
+	h1=patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	hold on;
+	text(sum(x(edges(:,1:2)),2)/2,sum(y(edges(:,1:2)),2)/2,sum(z(edges(:,1:2)),2)/2,...
+		num2str(transpose(1:size(edges,1))),...
+		'backgroundcolor',[0.8 0.9 0.8],'HorizontalAlignment','center','VerticalAlignment','middle');
+else
+	error('plot_edges: 3d plot of edges not supported yet!');
+end
+
+%apply options
+options=addfielddefault(options,'title','Edges');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_elementnumbering.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_elementnumbering.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_elementnumbering.m	(revision 5901)
@@ -0,0 +1,57 @@
+function plot_elementnumbering(md,options,width,i);
+%PLOT_ELEMENTNUMBERING - plot element numbering
+%
+%   Usage:
+%      plot_elementnumbering(md,options,width,i);
+%
+%   See also: PLOTMODEL, PLOT_UNIT, PLOT_MANAGER
+
+subplot(width,width,i); 
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+[elementnumbers datatype]=processdata(md,[1:md.numberofelements]',options);
+
+%plot
+if is2d
+	%plot mesh 
+	A=elements(:,1); B=elements(:,2); C=elements(:,3);
+	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+
+	%highlight
+	pos=getfieldvalue(options,'highlight',[]);
+	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3);
+	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+
+	%numbering
+	text(sum(x(elements(:,1:3)),2)/3,sum(y(elements(:,1:3)),2)/3,sum(z(elements(:,1:3)),2)/3,...
+		num2str(transpose(1:size(elements,1))),...
+		'HorizontalAlignment','center','VerticalAlignment','middle');
+else
+	%plot mesh 
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+
+	%highlight
+	pos=getfieldvalue(options,'highlight',[]);
+	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3);
+	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','none','EdgeColor','black');
+
+	%numbering
+	text(sum(x(elements(:,1:6)),2)/6,sum(y(elements(:,1:6)),2)/6,sum(z(elements(:,1:6)),2)/6,...
+		num2str(transpose(1:size(elements,1))),...
+		'HorizontalAlignment','center','VerticalAlignment','middle');
+end
+
+%apply options
+options=addfielddefault(options,'title','Element numbering');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_elementstype.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_elementstype.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_elementstype.m	(revision 5901)
@@ -0,0 +1,101 @@
+function plot_elementstype(md,options,width,i);
+%PLOT_ELEMENTSTYPE - plot elements type
+%
+%   Usage:
+%      plot_elementstype(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+[data datatype]=processdata(md,md.elements_type,options);
+
+%edgecolor?
+edgecolor=getfieldvalue(options,'edgecolor','none');
+
+%plot
+subplot(width,width,i);
+
+if is2d
+	%Hutter elements
+	posH=find(data==HutterApproximationEnum);
+	A=elements(posH,1); B=elements(posH,2); C=elements(posH,3); 
+	p1=patch( 'Faces', [A B C], 'Vertices', [x y z],'CData',HutterApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	%MacAyeal element
+	posH=find(data==MacAyealApproximationEnum);
+	A=elements(posH,1); B=elements(posH,2); C=elements(posH,3); 
+	p2=patch( 'Faces', [A B C], 'Vertices', [x y z],'CData',MacAyealApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	%Pattyn element
+	posH=find(data==PattynApproximationEnum);
+	A=elements(posH,1); B=elements(posH,2); C=elements(posH,3); 
+	p3=patch( 'Faces', [A B C], 'Vertices', [x y z],'CData',PattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	%MacAyealPattyn element
+	posH=find(data==MacAyealPattynApproximationEnum);
+	A=elements(posH,1); B=elements(posH,2); C=elements(posH,3); 
+	p5=patch( 'Faces', [A B C], 'Vertices', [x y z],'CData',MacAyealPattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	%Stokes elements
+	alpha=0.35;
+	posS=find(data==StokesApproximationEnum);
+	if ~isempty(posS)
+		A=elements(posS,1); B=elements(posS,2); C=elements(posS,3);
+	%	p4=patch( 'Faces', [A B C], 'Vertices', [x y z],'CData',StokesApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor,'EdgeAlpha',alpha,'FaceAlpha',alpha);
+	%	legend([p1 p2 p3 p4],'Hutter''s elements','MacAyeal''s elements','Pattyn''s elements','Stokes''s elements');
+	else
+		legend([p1 p2 p3 p5],'Hutter''s elements','MacAyeal''s elements','Pattyn''s elements','MacAyealPattyn''s elements');
+	end
+else
+	%Hutter elements
+	posH=find(data==HutterApproximationEnum);
+	A=elements(posH,1); B=elements(posH,2); C=elements(posH,3); D=elements(posH,4); E=elements(posH,5); F=elements(posH,6);
+	p1=patch( 'Faces', [A B C],'Vertices', [x y z],'CData', HutterApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'CData', HutterApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'CData', HutterApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'CData', HutterApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'CData', HutterApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	%MacAyeal elements
+	posM=find(data==MacAyealApproximationEnum);
+	A=elements(posM,1); B=elements(posM,2); C=elements(posM,3); D=elements(posM,4); E=elements(posM,5); F=elements(posM,6);
+	p2=patch( 'Faces', [A B C],'Vertices', [x y z],'CData', MacAyealApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'CData', MacAyealApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'CData', MacAyealApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'CData', MacAyealApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'CData', MacAyealApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	%Pattyn elements
+	posP=find(data==PattynApproximationEnum);
+	A=elements(posP,1); B=elements(posP,2); C=elements(posP,3); D=elements(posP,4); E=elements(posP,5); F=elements(posP,6);
+	p3=patch( 'Faces', [A B C],'Vertices', [x y z],'CData', PattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'CData', PattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'CData', PattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'CData', PattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'CData', PattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	%Stokes elements
+	posS=find(data==StokesApproximationEnum);
+	A=elements(posS,1); B=elements(posS,2); C=elements(posS,3); D=elements(posS,4); E=elements(posS,5); F=elements(posS,6);
+	p4=patch( 'Faces', [A B C],'Vertices', [x y z],'CData', StokesApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'CData', StokesApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'CData', StokesApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'CData', StokesApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'CData', StokesApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	%MacAyealPattyn elements
+	posP=find(data==MacAyealPattynApproximationEnum);
+	A=elements(posP,1); B=elements(posP,2); C=elements(posP,3); D=elements(posP,4); E=elements(posP,5); F=elements(posP,6);
+	p5=patch( 'Faces', [A B C],'Vertices', [x y z],'CData', MacAyealPattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'CData', MacAyealPattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'CData', MacAyealPattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'CData', MacAyealPattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'CData', MacAyealPattynApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	%PattynStokes elements
+	PosPS=find(data==PattynStokesApproximationEnum);
+	A=elements(PosPS,1); B=elements(PosPS,2); C=elements(PosPS,3); D=elements(PosPS,4); E=elements(PosPS,5); F=elements(PosPS,6);
+	p6=patch( 'Faces', [A B C],'Vertices', [x y z],'CData', PattynStokesApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'CData', PattynStokesApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'CData', PattynStokesApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'CData', PattynStokesApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'CData', PattynStokesApproximationEnum,'FaceColor','flat','EdgeColor',edgecolor);
+	legend([p1 p2 p3 p4 p5 p6],'Hutter''s elements','MacAyeal''s elements','Pattyn''s elements','Stokes''s elements','MacAyealPattyn''s elements','PattynStokes''s elements');
+end
+
+%apply options
+options=addfielddefault(options,'title','Elements type');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_gridnumbering.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_gridnumbering.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_gridnumbering.m	(revision 5901)
@@ -0,0 +1,51 @@
+function plot_gridnumbering(md,options,width,i);
+%PLOT_GRIDNUMBERING - plot grid numbering
+%
+%   Usage:
+%      plot_gridnumbering(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+[gridnumbers datatype]=processdata(md,[1:md.numberofgrids]',options);
+
+%plot
+subplot(width,width,i); 
+
+if is2d
+	%plot mesh 
+	A=elements(:,1); B=elements(:,2); C=elements(:,3);
+	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+
+	%numbering
+	text(x,y,z,num2str(transpose(1:size(x,1))),...
+		'backgroundcolor',[0.8 0.9 0.8],'HorizontalAlignment','center','VerticalAlignment','middle');
+
+	%Highlight
+	pos=getfieldvalue(options,'highlight',[]);
+	text(x(pos),y(pos),z(pos),num2str(transpose(pos)),...
+		'backgroundcolor',[1 0 0],'HorizontalAlignment','center','VerticalAlignment','middle');
+else
+	%plot mesh 
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+
+	%numbering
+	text(x,y,z,num2str(transpose(1:size(x,1))),...
+		'backgroundcolor',[0.8 0.9 0.8],'HorizontalAlignment','center','VerticalAlignment','middle');
+
+	%Highlight
+	pos=getfieldvalue(options,'highlight',[]);
+	text(x(pos),y(pos),z(pos),num2str(transpose(pos)),...
+		'backgroundcolor',[1 0 0],'HorizontalAlignment','center','VerticalAlignment','middle');
+end
+
+%apply options
+options=addfielddefault(options,'title','Grid numbering');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_highlightelements.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_highlightelements.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_highlightelements.m	(revision 5901)
@@ -0,0 +1,51 @@
+function plot_highlightelements(md,options,width,i);
+%PLOT_HIGHLIGHTELEMENTS - plot selected elements
+%
+%   Usage:
+%      plot_highlightelements(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%plot mesh boundaries
+subplot(width,width,i); 
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+[elementnumbers datatype]=processdata(md,[1:md.numberofelements]',options);
+
+%plot
+if is2d
+	%plot mesh 
+	A=elements(:,1); B=elements(:,2); C=elements(:,3);
+	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+
+	%Highlight
+	pos=getfieldvalue(options,'highlight',[]);
+	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3);
+	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+else
+	%plot mesh 
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+
+	%Highlight
+	pos=getfieldvalue(options,'highlight',[]);
+	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); D=elements(pos,4); E=elements(pos,5); F=elements(pos,6);
+	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [0.9 0.5 0.5],'FaceColor','flat','EdgeColor','black');
+end
+
+%apply options
+if ~exist(options,'highlight')
+	disp('highlightelements warning : highlight option empty, not element highlighted');
+end
+options=addfielddefault(options,'title','Highlighted Elements');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_highlightgrids.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_highlightgrids.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_highlightgrids.m	(revision 5901)
@@ -0,0 +1,46 @@
+function plot_highlightgrids(md,options,width,i);
+%PLOT_HIGHLIGHTGRIDS - plot selected grids
+%
+%   Usage:
+%      plot_highlightgrids(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+[gridnumbers datatype]=processdata(md,[1:md.numberofgrids]',options);
+
+%plot
+subplot(width,width,i); 
+
+if is2d
+	%plot mesh 
+	A=elements(:,1); B=elements(:,2); C=elements(:,3);
+	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+
+	%Highlight
+	pos=getfieldvalue(options,'highlight',[]);
+	text(x(pos),y(pos),z(pos),num2str(transpose(pos)),...
+		'backgroundcolor',[1 0 0],'HorizontalAlignment','center','VerticalAlignment','middle');
+else
+	%plot mesh 
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+
+	%Highlight
+	pos=getfieldvalue(options,'highlight',[]);
+	text(x(pos),y(pos),z(pos),num2str(transpose(pos)),...
+		'backgroundcolor',[1 0 0],'HorizontalAlignment','center','VerticalAlignment','middle');
+end
+
+%apply options
+if ~exist(options,'highlight')
+	disp('highlightgrids warning : highlight option empty, not grid highlighted');
+end
+options=addfielddefault(options,'title','Highlighted Grids');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_importancefactors.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_importancefactors.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_importancefactors.m	(revision 5901)
@@ -0,0 +1,83 @@
+function plot_importancefactors(md,options,width,ii);
+%PLOT_IMPORTANCEFACTORS - plot importance factors
+%
+%   Usage:
+%      plot_importancefactors(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%first recover design variable descriptor
+if exist(options,'designvariable'),
+	descriptor=getfieldvalue(options,'designvariable');
+else
+	error('plot_importancefactors error message: Need to supply design variable descriptor');
+end
+descriptorlength=length(descriptor);
+
+%then recover responsfunction name
+if exist(options,'responsefunction'),
+	responsefunctiondescriptor=getfieldvalue(options,'responsefunction');
+else
+	error('plot_importancefactors error message: Need to supply response function descriptor');
+end
+
+%go through all response functions and find the one corresponding to the correct responsefunctiondescriptor
+responsefunctions=md.dakotaresults{2};
+found=0;
+for i=1:length(responsefunctions),
+	if strcmpi(responsefunctions(i).descriptor,responsefunctiondescriptor),
+		found=i;
+		break;
+	end
+end
+if ~found,
+	error('plot_importancefactors error message: could not find correct response function');
+end
+responsefunctions=responsefunctions(found);
+nfun=size(responsefunctions.desvar,1);
+
+%Now recover response to the correct desgin variable
+importancefactors=zeros(md.npart,1);
+count=0;
+for i=1:nfun,
+	desvar=responsefunctions.desvar{i};
+	if strncmpi(desvar,descriptor,descriptorlength),
+		count=count+1;
+		importancefactors(count)=responsefunctions.impfac(i);
+	end
+end
+if count==0,
+	error('plot_importancefactors error message: could not find to response functions with corresponding design variable');
+end
+
+%log?
+if exist(options,'log'),
+	logvalue=getfieldvalue(options,'log');
+	importancefactors=log(importancefactors)/log(logvalue);
+end
+
+%Ok, get partitioning.
+[epart npart]=MeshPartition(md,md.npart);
+
+%distribute importance factor
+gridimportance=importancefactors(npart);
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+
+%edgecolor
+edgecolor=getfieldvalue(options,'edgecolor','none');
+
+%standard plot:
+subplot(width,width,ii);
+
+%ok, plot gridimportance now.
+if is2d,
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); 
+	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', gridimportance,'FaceColor','interp','EdgeColor',edgecolor);
+else
+	error('plot_importancefactors error message: 3d meshes not supported yet');
+end
+
+%apply options
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_manager.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_manager.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_manager.m	(revision 5901)
@@ -0,0 +1,200 @@
+function plot_manager(md,options,subplotwidth,nlines,ncols,i);
+%PLOT__MANAGER - distribute the plots, called by plotmodel
+%
+%   Usage:
+%      plot_manager(md,options,subplotwidth,i);
+%
+%   See also: PLOTMODEL, PLOT_UNIT
+
+%parse options and get a structure of options. 
+options=checkplotoptions(md,options);
+
+%get data to be displayed
+data=getfieldvalue(options,'data');
+
+%figure out if this is a special plot
+if ischar(data),
+
+	switch data,
+
+		case 'boundaries',
+			plot_boundaries(md,options,subplotwidth,i);
+			return;
+		case 'BC',
+			plot_BC(md,options,subplotwidth,i,data);
+			return;
+		case 'edges'
+			plot_edges(md,options,subplotwidth,i,data)
+			return
+		case 'elementnumbering',
+			plot_elementnumbering(md,options,subplotwidth,i);
+			return;
+		case 'highlightelements',
+			plot_highlightelements(md,options,subplotwidth,i);
+			return;
+		
+		case 'qmumean',
+			plot_qmumean(md,options,nlines,ncols,i);
+			return;
+		
+		case 'qmustddev',
+			plot_qmustddev(md,options,nlines,ncols,i);
+			return;
+		
+		case 'qmuhistnorm',
+			plot_qmuhistnorm(md,options,subplotwidth,i);
+			return;
+
+		case 'qmu_mass_flux_segments',
+			plot_qmu_mass_flux_segments(md,options,nlines,ncols,i);
+			return;
+
+		case 'part_hist',
+			plot_parthist(md,options,nlines,ncols,i);
+			return;
+		case 'elements_type',
+			plot_elementstype(md,options,subplotwidth,i);
+			return;
+		case 'gridnumbering',
+			plot_gridnumbering(md,options,subplotwidth,i);
+			return;
+		
+		case 'highlightgrids',
+			plot_highlightgrids(md,options,subplotwidth,i);
+			return;
+		case {'basal_drag','basal_dragx','basal_dragy'},
+			plot_basaldrag(md,options,subplotwidth,i,data);
+			return;
+		case 'driving_stress',
+			plot_drivingstress(md,options,subplotwidth,i);
+			return;
+		case 'mesh',
+			plot_mesh(md,options,nlines,ncols,i);
+			return;
+		case 'none',
+			plot_none(md,options,nlines,ncols,i);
+			return;
+		case 'penalties',
+			plot_penalties(md,options,subplotwidth,i);
+			return;
+		case 'partition',
+			plot_partition(md,options,nlines,ncols,i);
+			return;
+		case 'riftvel',
+			plot_riftvel(md,options,nlines,ncols,i);
+			return;
+		case 'rifts',
+			plot_rifts(md,options,nlines,ncols,i);
+			return;
+		case 'riftrelvel',
+			plot_riftrelvel(md,options,nlines,ncols,i);
+			return;
+		case 'riftpenetration',
+			plot_riftpenetration(md,options,nlines,ncols,i);
+			return;
+		case 'riftfraction',
+			plot_riftfraction(md,options,nlines,ncols,i);
+			return;
+		case 'sarpwr',
+			plot_sarpwr(md,options,subplotwidth,i)
+			return
+		case 'pressureload'
+			plot_pressureload(md,options,subplotwidth,i,data)
+			return
+		case 'segments'
+			plot_segments(md,options,subplotwidth,i,data)
+			return
+		case {'strainrate_tensor','strainrate','strainrate_principal','strainrate_principalaxis1','strainrate_principalaxis2','strainrate_principalaxis3',...
+				'stress_tensor','stress','stress_principal','stress_principalaxis1','stress_principalaxis2','stress_principalaxis3',...
+				'deviatoricstress_tensor','deviatoricstress','deviatoricstress_principal','deviatoricstress_principalaxis1','deviatoricstress_principalaxis2','deviatoricstress_principalaxis3'},
+			plot_tensor(md,options,subplotwidth,i,data);
+			return;
+		case 'thermaltransient_results',
+			plot_thermaltransient_results(md,options,subplotwidth,i);
+			return;
+		case 'transient_movie',
+			plot_transient_movie(md,options,subplotwidth,i);
+			return;
+		case 'transient_results',
+			plot_transient_results(md,options,subplotwidth,i);
+		case {'transient_thickness','transient_bed','transient_surface','transient_temperature','transient_melting','transient_vel','transient_vx','transient_vy','transient_vz','transient_pressure'}
+			plot_transient_field(md,options,subplotwidth,i,data);
+			return;
+
+	otherwise,
+
+		if isfield(struct(md),data)
+			data=eval(['md.' data ';']);
+		else
+			error('plot error message: data provided not supported yet. Type plotdoc for help');
+		end
+	end
+end
+
+%Figure out if this is a semi-transparent plot.
+if exist(options,'overlay'),
+	plot_overlay(md,data,options,nlines,ncols,i);
+	return;
+end
+
+%Figure out if this is a Section plot
+if exist(options,'sectionvalue')
+	plot_section(md,data,options,nlines,ncols,i);
+	return;
+end
+
+%process data and model
+[x y z elements is2d]=processmesh(md,data,options);
+[data2 datatype]=processdata(md,data,options);
+
+%standard plot:
+subplot(nlines,ncols,i);
+
+%apply position change: 
+if exist(options,'position')
+	set(gca,'Position',getfieldvalue(options,'position'));
+end
+
+%plot unit
+plot_unit(x,y,z,elements,data2,is2d,datatype,options);
+
+%apply all options
+if datatype==3,
+	options=changefieldvalue(options,'colorbar',2);
+	if exist(options,'contourlevels'),
+		data2=data;
+	end
+end
+
+applyoptions(md,data2,options);
+
+%plot inset if requested
+if exist(options,'inset'),
+
+	%get inset relative position (x,y,width,height)
+	insetpos=getfieldvalue(options,'insetpos',[0.56 0.55 0.35 0.35]);
+	%get current plos position
+	cplotpos=get(gca,'pos');
+	%compute inset position
+	PosInset=[cplotpos(1)+insetpos(1)*cplotpos(3),cplotpos(2)+insetpos(2)*cplotpos(4), insetpos(3)*cplotpos(3), insetpos(4)*cplotpos(4)];
+	%show pos
+	if strcmpi(getfieldvalue(options,'showinset','off'),'on')
+		X1=getfieldvalue(options,'insetx',[min(x) max(x)]);
+		Y1=getfieldvalue(options,'insety',[min(y) max(y)]);
+		line(X1([1 2 2 1 1]),Y1([1 1 2 2 1]),zeros(1,5),'Color','k','LineWidth',2);
+	end
+
+	%plot inset
+	axes('pos',PosInset);
+	box('on')
+	plot_unit(x,y,z,elements,data2,is2d,datatype,options);
+
+	%applay options
+	options=changefieldvalue(options,'colorbar',0);
+	options=changefieldvalue(options,'text',{});
+	options=changefieldvalue(options,'latlon','off');
+	options=changefieldvalue(options,'axis','equal off');
+	options=changefieldvalue(options,'xlim',getfieldvalue(options,'insetx',[min(x) max(x)]));
+	options=changefieldvalue(options,'ylim',getfieldvalue(options,'insety',[min(y) max(y)]));
+	applyoptions(md,data2,options);
+end
Index: /issm/trunk/src/m/model/plot/plot_mesh.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_mesh.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_mesh.m	(revision 5901)
@@ -0,0 +1,31 @@
+function plot_mesh(md,options,nlines,ncols,i);
+%PLOT_MESH - plot model mesh
+%
+%   Usage:
+%      plot_mesh(md,options,nlines,ncols,i);
+%
+%   See also: PLOTMODEL
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+
+%plot mesh
+subplot(nlines,ncols,i); 
+
+%plot mesh
+if is2d
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); 
+	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+else
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+end
+
+%apply options
+options=addfielddefault(options,'title','Mesh');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_none.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_none.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_none.m	(revision 5901)
@@ -0,0 +1,13 @@
+function plot_none(md,options,nlines,ncols,i);
+%PLOT_NONE - plot nothing, just apply options
+%
+%   Usage:
+%      plot_mesh(md,options,nlines,ncols,i);
+%
+%   See also: PLOTMODEL
+
+options=addfielddefault(options,'colorbar','none');
+options=addfielddefault(options,'axis','equal');
+
+%apply options
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_overlay.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_overlay.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_overlay.m	(revision 5901)
@@ -0,0 +1,164 @@
+function plot_overlay(md,data,options,plotlines,plotcols,i)
+%PLOT_OVERLAY - superimpose radar image to a given field
+%
+%   Usage:
+%      plot_overlay(md,options,plotlines,plotcols,i)
+%
+%   See also: PLOTMODEL
+
+%process mesh and data
+[x y z elements is2d]=processmesh(md,[],options);
+[data datatype]=processdata(md,data,options);
+
+%check is2d
+if ~is2d, 
+	error('buildoverlay error message: overlay not supported for 3d meshes, project on a layer');
+end
+if datatype==3,
+	error('buildoverlay error message: overlay not supported for quiver plots');
+end
+
+% radar power {{{1
+if ~any(isnan(md.sarxm)) & ~any(isnan(md.sarym)) & ~any(isnan(md.sarpwr)),
+	disp('plot_overlay info: the radar image held by the model is being used');
+else
+	t1=clock; fprintf('%s','Extracting radar image...');
+	xlim=getfieldvalue(options,'xlim',[min(x) max(x)])/getfieldvalue(options,'unit',1);
+	ylim=getfieldvalue(options,'ylim',[min(y) max(y)])/getfieldvalue(options,'unit',1);
+	md=radarpower(md,getfieldvalue(options,'hem',md.hemisphere),xlim,ylim,getfieldvalue(options,'highres',0));
+	t2=clock;fprintf('%s\n',[' done (' num2str(etime(t2,t1)) ' seconds)']);
+end%}}}
+
+% InterpFromMeshToGrid -> data_grid {{{1
+redo=1;
+if (ischar(data) & isstruct(md.mesh2grid_parameters) & ismember(data,mesh2grid_parameters)),
+	choice=input(['mesh2grid has already been called for the parameter ''' data '''. Do you want to call it again (y/n)?'],'s');
+	if strcmp(choice,'y')
+		disp('use previous mesh2grid result');
+		x_m=md.mesh2grid_x_m;
+		y_m=md.mesh2grid_y_m;
+		data_grid=md.mesh2grid_data;
+		redo=0;
+	end
+end
+if redo,
+	%apply caxis if required
+	if exist(options,'caxis'),
+		caxis_opt=getfieldvalue(options,'caxis');
+		data(find(data<caxis_opt(1)))=caxis_opt(1);
+		data(find(data>caxis_opt(2)))=caxis_opt(2);
+	end
+
+	%use InterpFromMeshToGrid to get an gridded data to display using imagesc
+	xlim=getfieldvalue(options,'xlim',[min(x) max(x)]);
+	ylim=getfieldvalue(options,'ylim',[min(y) max(y)]);
+	cornereast =min(xlim);
+	cornernorth=max(ylim);
+	xspacing=(max(xlim)-min(xlim))/(length(md.sarxm));
+	yspacing=(max(ylim)-min(ylim))/(length(md.sarym));
+	nlines=length(md.sarym);
+	ncols =length(md.sarxm);
+	t1=clock; fprintf('%s','Interpolating data on grid...');
+	[x_m y_m data_grid]=InterpFromMeshToGrid(elements,x,y,data,cornereast,cornernorth,xspacing,yspacing,nlines,ncols,getfieldvalue(options,'cutoff',1.5));
+	t2=clock;fprintf('%s\n',[' done (' num2str(etime(t2,t1)) ' seconds)']);
+end%}}}
+
+%Generate RGB image{{{1
+
+%Build hsv color image from radar and results
+radar=md.sarpwr;
+transparency=getfieldvalue(options,'alpha',1.5);  %Rignot's setting: 1.5
+cutoff=getfieldvalue(options,'cutoff',1.5);       %Rignot's setting: 1.5
+
+%intensity
+v_data=radar/max(radar(:)); %For the principla image, use radar power as intensity
+v_coba=ones(256,1);         %For the colorbar: maximal intensity
+
+%hue
+data_grid(find(data_grid<cutoff))=cutoff;   %cut all values below cutoff
+data_coba=linspace(max(min(data(:)),cutoff),max(max(data(:)),cutoff),256);%prepare colorbar (256 values between min and max)
+h_data=bytscl(data_grid)/(255+1);           %scale between 0 and 1 (log applied in processdata)
+h_coba=bytscl(data_coba)/(255+1);           %scale between 0 and 1
+
+%saturation
+s_data=(0.5+10.^data_grid/125)/transparency;s_data(find(s_data>1))=1;s_data(find(s_data<0))=0;
+s_coba=(0.5+10.^data_coba/125)/transparency;s_coba(find(s_coba>1))=1;s_coba(find(s_coba<0))=0;
+s_data(find(data_grid==cutoff))=0;
+s_coba(find(data_coba==cutoff))=0;
+
+%Transform hsv to rgb
+image_hsv=zeros(size(data_grid,1),size(data_grid,2),3);
+image_hsv(:,:,1)=h_data;
+image_hsv(:,:,2)=s_data;
+image_hsv(:,:,3)=v_data;
+image_rgb=hsv2rgb(image_hsv);
+colorbar_hsv=zeros(size(data_coba,2),size(data_coba,1),3);
+colorbar_hsv(:,:,1)=h_coba;
+colorbar_hsv(:,:,2)=s_coba;
+colorbar_hsv(:,:,3)=v_coba;
+colorbar_rgb=hsv2rgb(colorbar_hsv);
+%}}}
+
+%Select plot area 
+subplot(plotlines,plotcols,i);
+%uncomment following lines to have more space
+%P=get(gca,'pos');
+%P(3)=P(3)+0.05;
+%P(2)=P(2)+0.08;
+%P(1)=P(1)-0.02;
+%set(gca,'pos',P);
+
+%Plot: 
+imagesc(md.sarxm*getfieldvalue(options,'unit',1),md.sarym*getfieldvalue(options,'unit',1),image_rgb);set(gca,'YDir','normal');
+
+%last step: mesh overlay?
+if exist(options,'edgecolor')
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); 
+	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor',getfieldvalue(options,'edgecolor'));
+end
+
+%Apply options {{{1
+%Apply options, without colorbar and without grid
+iscolorbar=getfieldvalue(options,'colorbar',1);
+options=changefieldvalue(options,'colorbar',0);
+options=addfielddefault(options,'axis','equal off');
+options=addfielddefault(options,'colorbarpos',[0.80 0.70 0.02 0.15]);
+applyoptions(md,data,options);
+
+%colorbar
+if iscolorbar,
+
+	%create colorbar with correct colors and position
+	%colorbar_rgb=buildoverlaycolorbar(md,data,getfieldvalue(options,'aplha',1.5));
+	colorbar_handle=colorbar; 
+	colorbar_image_handle=get(colorbar_handle,'Children'); 
+	set(colorbar_image_handle,'CData',colorbar_rgb);
+	set(colorbar_handle,'Position',getfieldvalue(options,'colorbarpos'));
+	set(colorbar_handle,'FontSize',getfieldvalue(options,'colorbarfontsize',14));
+
+	%modify ticks.
+	scalestring=get(colorbar_handle,'YTickLabel');
+	numvalues=length(get(colorbar_handle,'YTick'));
+
+	scalestring=[];
+	scaleminmax=[max(min(data),cutoff) max(data)];
+	for i=1:numvalues,
+		fraction=(i-1)/(numvalues-1);
+		scalevalues(i)=scaleminmax(1)+(scaleminmax(2)-scaleminmax(1))*fraction;
+		if exist(options,'log'),
+			logvalue=getfieldvalue(options,'log');
+			scalestring=[scalestring; sprintf('%-8.4g',round_ice(logvalue^scalevalues(i),2) )];
+		else
+			scalestring=[scalestring; sprintf('%-8.4g',round_ice(scalevalues(i),2) )];
+		end
+	end
+	set(colorbar_handle,'YTickLabel',scalestring);
+	set(colorbar_handle,'YColor',getfieldvalue(options,'FontColor','k'));
+	if exist(options,'colorbartitle'),
+		backup=gca;
+		axes(colorbar_handle);lab=title(getfieldvalue(options,'colorbartitle'),'Color',getfieldvalue(options,'FontColor','k'));
+		set(lab,'Rotation',getfieldvalue(options,'colorbartitlerotation',0));
+		set(lab,'VerticalAlignment','bottom');
+		axes(backup);
+	end
+end%}}}
Index: /issm/trunk/src/m/model/plot/plot_parthist.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_parthist.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_parthist.m	(revision 5901)
@@ -0,0 +1,34 @@
+function plot_parthist(md,options,nlines,ncols,i);
+%PLOT_PARTHIST - plot partitioning histogram
+%
+%   Usage:
+%      plot_parthist(md,options,nlines,ncols,i);
+%
+%   See also: PLOTMODEL
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+
+%plot mesh
+subplot(nlines,ncols,i); 
+
+imin=min(md.part);
+imax=max(md.part);
+
+part=zeros(imax-imin+1,2);
+
+for i=imin:imax
+    ind=find(md.part == i);
+    part(i-imin+1,1)=length(ind);
+	part(i-imin+1,2)=sum(md.vwgt(ind));
+end
+
+subplot(2,1,1)
+bar(imin:imax,part(:,1));
+xlim([imin imax])
+title('Number of Nodes in Each Partition')
+
+subplot(2,1,2)
+bar(imin:imax,part(:,2));
+xlim([imin imax])
+title('Total weight in Each Partition')
Index: /issm/trunk/src/m/model/plot/plot_penalties.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_penalties.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_penalties.m	(revision 5901)
@@ -0,0 +1,48 @@
+function plot_penalties(md,options,width,i);
+%PLOT_PENALTIES - plot penalties
+%
+%   Usage:
+%      plot_penalties(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+
+%plot mesh penalties
+subplot(width,width,i); 
+
+%units
+if exist(options,'unit'),
+	unit=getfieldvalue(options,'unit');
+	x=x*unit;
+	y=y*unit;
+	z=z*unit;
+end
+
+if ~md.dim==3,
+	error('no penalties to plot for ''2d'' model');
+elseif isempty(md.penalties),
+	disp('no penalty applied in this model');
+	return;
+else
+	%plot mesh
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+	patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+
+	hold on;
+	for (i=1:size(md.penalties,1)),
+		P1=plot3(x(md.penalties(i,1)),y(md.penalties(i,1)),z(md.penalties(i,1)),'ro','MarkerSize',15,'MarkerFaceColor','r');
+		P2=plot3(x(md.penalties(i,:)),y(md.penalties(i,:)),z(md.penalties(i,:)),'bo-','LineWidth',2,'MarkerSize',8,'MarkerFaceColor','b');
+	end
+	legend([P1 P2],'MacAyeal''s penalized grids','Pattyn''s penalized grids');
+end
+
+%apply options
+options=addfielddefault(options,'title','Penalties');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_pressureload.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_pressureload.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_pressureload.m	(revision 5901)
@@ -0,0 +1,93 @@
+function plot_pressureload(md,options,width,i,data);
+%PLOT_PRESSURELOAD - plot segment on neumann BC
+%
+%   Usage:
+%      plot_pressureload(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%plot mesh boundaries
+subplot(width,width,i); 
+
+%process mesh and data
+[x y z elements is2d]=processmesh(md,[],options);
+pressureload=md.pressureload;
+
+if (md.dim==2),
+
+	%plot mesh
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); 
+	h1=patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	hold on;
+
+	%highlight elements on neumann
+	pos=find(pressureload(:,end)==WaterEnum());
+	pos=pressureload(pos,end-1);
+	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); 
+	h2=patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','blue','EdgeColor','black');
+	pos=find(pressureload(:,end)==AirEnum());
+	pos=pressureload(pos,end-1);
+	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); 
+	h3=patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','green','EdgeColor','black');
+
+	%display arrows pointing outward
+	xstart=mean(x(pressureload(:,1:end-2)),2);
+	ystart=mean(y(pressureload(:,1:end-2)),2);
+	length=sqrt((x(pressureload(:,1))-x(pressureload(:,2))).^2 + (y(pressureload(:,1))-y(pressureload(:,2))).^2 );
+	normal(:,1)=cos(atan2((x(pressureload(:,1))-x(pressureload(:,2))) , (y(pressureload(:,2))-y(pressureload(:,1)))));
+	normal(:,2)=sin(atan2((x(pressureload(:,1))-x(pressureload(:,2))) , (y(pressureload(:,2))-y(pressureload(:,1)))));
+	xend=xstart+length.*normal(:,1);
+	yend=ystart+length.*normal(:,2);
+	q=quiver(xstart,ystart,xend-xstart,yend-ystart); hold on;
+	h4=plot(xstart,ystart,'r*');
+else
+
+	%plot mesh
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+	h1=patch( 'Faces', [A B C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	hold on;
+
+	%highlight elements on neumann
+	pos=find(pressureload(:,end)==WaterEnum());
+	pos=pressureload(pos,end-1);
+	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); D=elements(pos,4); E=elements(pos,5); F=elements(pos,6);
+	h2=patch( 'Faces', [A B C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','blue','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','blue','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','blue','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','blue','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','blue','EdgeColor','black');
+	pos=find(pressureload(:,end)==AirEnum());
+	pos=pressureload(pos,end-1);
+	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); D=elements(pos,4); E=elements(pos,5); F=elements(pos,6);
+	h3=patch( 'Faces', [A B C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','green','EdgeColor','black');
+	patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','green','EdgeColor','black');
+	patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','green','EdgeColor','black');
+	patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','green','EdgeColor','black');
+	patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','green','EdgeColor','black');
+
+	%display arrows pointing outward
+	xstart=mean(x(pressureload(:,1:end-2)),2);
+	ystart=mean(y(pressureload(:,1:end-2)),2);
+	zstart=mean(z(pressureload(:,1:end-2)),2);
+	length=sqrt((x(pressureload(:,1))-x(pressureload(:,2))).^2 + (y(pressureload(:,1))-y(pressureload(:,2))).^2 );
+	normal(:,1)=cos(atan2((x(pressureload(:,1))-x(pressureload(:,2))) , (y(pressureload(:,2))-y(pressureload(:,1)))));
+	normal(:,2)=sin(atan2((x(pressureload(:,1))-x(pressureload(:,2))) , (y(pressureload(:,2))-y(pressureload(:,1)))));
+	xend=xstart+length.*normal(:,1);
+	yend=ystart+length.*normal(:,2);
+	q=quiver3(xstart,ystart,zstart,xend-xstart,yend-ystart,0); hold on;
+	h4=plot3(xstart,ystart,zstart,'r*');
+end
+
+%legend (disable warnings)
+warning off
+legend([h2,h3,q],'element on ice front (Water)','element on ice front (Air)','normal vectors')
+warning on
+
+%apply options
+options=addfielddefault(options,'title','Neumann boundary conditions');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_qmu_mass_flux_segments.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_qmu_mass_flux_segments.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_qmu_mass_flux_segments.m	(revision 5901)
@@ -0,0 +1,49 @@
+function plot_qmu_mass_flux_segments(md,options,nlines,ncols,i);
+%PLOT_QMU_MASS_FLUX_SEGMENTS - plot segments from the qmu analysis of mass fluxes
+%
+%   Usage:
+%      plot_qmu_mass_flux_segments(md,options,nlines,ncols,i);
+%
+
+subplot(nlines,ncols,i); 
+
+%process mesh and data
+[x y z elements is2d]=processmesh(md,[],options);
+
+allsegments=md.qmu_mass_flux_segments;
+
+if (md.dim==2),
+
+	%recover segments
+	hold on
+	for i=1:length(allsegments),
+		segments=allsegments{i};
+
+		%plot semgnets
+		for j=1:length(segments),
+			plot([segments(j,1) segments(j,3)],[segments(j,2) segments(j,4)]);
+		end
+		text(segments(j,1),segments(j,2),['Profile #' num2str(i)]);
+
+		%plot normals
+		
+		for j=1:length(segments),
+			xstart=mean([segments(j,1) segments(j,3)]);
+			ystart=mean([segments(j,2) segments(j,4)]);
+			length1=sqrt((segments(j,1)-segments(j,3)).^2 + (segments(j,2)-segments(j,4)).^2);
+			normal(:,1)=cos(atan2(segments(j,1)-segments(j,3) , segments(j,4)-segments(j,2)));
+			normal(:,2)=sin(atan2(segments(j,1)-segments(j,3) , segments(j,4)-segments(j,2)));
+			xend=xstart+length1.*normal(:,1);
+			yend=ystart+length1.*normal(:,2);
+			plot([xstart xend],[ystart yend],'r-');
+		end
+
+	end
+else
+	error('plot_qmu_mass_flux_segments: 3d plot of segments not supported yet!');
+end
+
+%apply options
+options=addfielddefault(options,'title','Mass Flux segments and normals');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_qmuhistnorm.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_qmuhistnorm.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_qmuhistnorm.m	(revision 5901)
@@ -0,0 +1,36 @@
+function plot_qmuhistnorm(md,options,width,i);
+
+%recover histnorm data
+if ~exist(options,'qmudata')
+	error('plot_qmuhistnorm error message: option qmudata is required');
+else
+	qmudata=getfieldvalue(options,'qmudata');
+end
+
+%process options for the qmu plot: 
+
+%    hmin          (numeric, minimum for histogram)
+%    hmax          (numeric, maximum for histogram)
+%    hnint         (numeric, number of intervals for histogram)
+%    ymin1         (numeric, minimum of histogram y-axis)
+%    ymax1         (numeric, maximum of histogram y-axis)
+%    ymin2         (numeric, minimum of cdf y-axis)
+%    ymax2         (numeric, maximum of cdf y-axis)
+%    cdfplt        (char, 'off' to turn off cdf line plots)
+%    cdfleg        (char, 'off' to turn off cdf legends)
+%
+
+qmuoptions='';
+
+if exist(options,'hmin'), hmin=getfieldvalue(options,'hmin'); qmuoptions=[qmuoptions ',''hmin'',' num2str(hmin)]; end
+if exist(options,'hmax'), hmax=getfieldvalue(options,'hmax'); qmuoptions=[qmuoptions ',''hmax'',' num2str(hmax)]; end
+if exist(options,'hnint'), hnint=getfieldvalue(options,'hnint'); qmuoptions=[qmuoptions ',''hnint'',' num2str(hnint)]; end
+if exist(options,'ymin1'), ymin1=getfieldvalue(options,'ymin1'); qmuoptions=[qmuoptions ',''ymin1'',' num2str(ymin1)]; end
+if exist(options,'ymax1'), ymax1=getfieldvalue(options,'ymax1'); qmuoptions=[qmuoptions ',''ymax1'',' num2str(ymax1)]; end
+if exist(options,'ymin2'), ymin2=getfieldvalue(options,'ymin2'); qmuoptions=[qmuoptions ',''ymin2'',' num2str(ymin2)]; end
+if exist(options,'ymax2'), ymax2=getfieldvalue(options,'ymax2'); qmuoptions=[qmuoptions ',''ymax2'',' num2str(ymax2)]; end
+if exist(options,'cdfplt'), cdfplt=getfieldvalue(options,'cdfplt'); qmuoptions=[qmuoptions ',''cdfplt'',''' cdfplt '''']; end
+if exist(options,'cdfleg'), cdfleg=getfieldvalue(options,'cdfleg'); qmuoptions=[qmuoptions ',''cdfleg'',''' cdfleg '''']; end
+
+%use qmu plot
+eval(['plot_hist_norm(qmudata' qmuoptions ');']);
Index: /issm/trunk/src/m/model/plot/plot_qmumean.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_qmumean.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_qmumean.m	(revision 5901)
@@ -0,0 +1,59 @@
+function plot_qmumean(md,options,nlines,ncols,i);
+%PLOT_QMUMEAN - plot mean of a scaled response 
+%
+%   Usage:
+%      plot_qmumean(md,options,nlines,ncols,i);
+%
+%   See also: PLOTMODEL
+
+%plot mesh
+subplot(nlines,ncols,i); 
+
+%edgecolor
+edgecolor=getfieldvalue(options,'edgecolor','none');
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+
+%find response function
+if exist(options,'qmudata'), 
+	descriptor=getfieldvalue(options,'qmudata'); 
+	if ~ischar(descriptor),
+		error('plot_qmumean error message:  descriptor should be a string');
+	end
+else 
+	error('plot_qmumean error message:  provide descriptor of response function in ''qmudata'' option');
+end
+
+%go pick up the response: 
+allresponses=md.dakotaresults.dresp_out;
+responses=zeros(md.npart,1);
+
+count=1;
+for i=1:length(allresponses),
+	d=allresponses(i).descriptor;
+	if strncmpi(d,'scaled_',7),
+		d=d(8:end);
+		if strncmpi(d,descriptor,length(descriptor)),
+			responses(count)=allresponses(i).mean;
+			count=count+1;
+		end
+	end
+end
+
+%log?
+if exist(options,'log'),
+	responses=log(responses)/log(getfieldvalue(options,'log'));
+end
+
+%now, project onto vertices
+responses_on_grid=responses(md.part+1);
+
+%plot
+A=elements(:,1); B=elements(:,2); C=elements(:,3); 
+patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', responses_on_grid,'FaceColor','interp','EdgeColor',edgecolor);
+
+%apply options
+options=addfielddefault(options,'title',['Mean distribution of ' descriptor]);
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_qmunormplot.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_qmunormplot.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_qmunormplot.m	(revision 5901)
@@ -0,0 +1,45 @@
+%
+%  plot a normal probability plot of the response functions.
+%
+%  []=plot_normplot(rfunc)
+%
+function []=plot_qmunormplot(rfunc,width,ii)
+
+if ~nargin
+    help plot_normplot
+    return
+end
+
+%%  assemble the data into a matrix
+
+desc=cell (1,length(rfunc));
+for i=1:length(rfunc)
+    ldata(i)=length(rfunc(i).sample);
+end
+data=zeros(max(ldata),length(rfunc));
+
+for i=1:length(rfunc)
+    desc(i)=cellstr(rfunc(i).descriptor);
+    data(1:ldata(i),i)=rfunc(i).sample;
+end
+
+%standard plot:
+subplot(width,width,ii);
+
+%%  draw the plot
+
+%  draw normal probability plot
+
+normplot(data)
+ax1=gca;
+
+%  add the annotation
+
+title('Normal Probability Plot of Design Variables and/or Response Functions')
+xlabel('Value')
+ylabel('Probability')
+
+hleg1=legend(ax1,desc,'Location','EastOutside',...
+             'Orientation','vertical','Interpreter','none');
+
+end
Index: /issm/trunk/src/m/model/plot/plot_qmustddev.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_qmustddev.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_qmustddev.m	(revision 5901)
@@ -0,0 +1,60 @@
+function plot_qmustddev(md,options,nlines,ncols,i);
+%PLOT_QMUMEAN - plot stddev of a scaled response 
+%
+%   Usage:
+%      plot_qmustddev(md,options,nlines,ncols,i);
+%
+%   See also: PLOTMODEL
+
+%plot mesh
+subplot(nlines,ncols,i); 
+
+%edgecolor
+edgecolor=getfieldvalue(options,'edgecolor','none');
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+
+%find response function
+if exist(options,'qmudata'), 
+	descriptor=getfieldvalue(options,'qmudata'); 
+	if ~ischar(descriptor),
+		error('plot_qmustddev error message:  descriptor should be a string');
+	end
+else 
+	error('plot_qmustddev error message:  provide descriptor of response function in ''qmudata'' option');
+end
+
+%go pick up the response: 
+allresponses=md.dakotaresults.dresp_out;
+responses=zeros(md.npart,1);
+
+count=1;
+for i=1:length(allresponses),
+	d=allresponses(i).descriptor;
+	if strncmpi(d,'scaled_',7),
+		d=d(8:end);
+		if strncmpi(d,descriptor,length(descriptor)),
+			responses(count)=allresponses(i).stddev/allresponses(i).mean*100;
+			count=count+1;
+		end
+	end
+end
+
+%log?
+if exist(options,'log'),
+	responses=log(responses)/log(getfieldvalue(options,'log'));
+end
+
+
+%now, project onto vertices
+responses_on_grid=responses(md.part+1);
+
+%plot
+A=elements(:,1); B=elements(:,2); C=elements(:,3); 
+patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', responses_on_grid,'FaceColor','interp','EdgeColor',edgecolor);
+
+%apply options
+options=addfielddefault(options,'title',['Stddev  distribution of ' descriptor ' in %']);
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_quiver.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_quiver.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_quiver.m	(revision 5901)
@@ -0,0 +1,26 @@
+function plot_quiver(x,y,u,v,options),
+%PLOT_QUIVER - quiver plot with colors
+%
+%   to be perfected tomorrow
+%
+%   Usage:
+%      plot_quiver(x,y,u,v,options)
+%
+%   Example:
+%      plot_quiver(md.x,md.y,md.vx,md.vy,options);
+
+%process fields
+[quivers,palette]=quiver_process(x,y,u,v,options);
+
+%loop over the number of colors
+hold on
+h=[];
+for i=1:quivers.numcolors
+	pos=find(quivers.colorind==i);
+	hprime=quiver(quivers.x(pos),quivers.y(pos),quivers.u(pos),quivers.v(pos),...
+		'Color',palette(i,:),'ShowArrowHead','on','AutoScale','off');
+	h=[h;hprime];
+end
+
+%take care of colorbar
+quiver_colorbar(quivers,options);
Index: /issm/trunk/src/m/model/plot/plot_quiver3.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_quiver3.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_quiver3.m	(revision 5901)
@@ -0,0 +1,104 @@
+function plot_quiver3(x,y,z,u,v,w,options),
+%PLOT_QUIVER3 - 3d quiver plot with colors
+%
+%   to be perfected tomorrow
+%
+%   Usage:
+%      plot_quiver3(x,y,z,u,v,w,options)
+%
+%   Example:
+%      plot_quiver(md.x,md.y,md.z,md.vx,md.vy,md.vz,options);
+
+%keep only non NaN elements
+pos=find(~isnan(x) & ~isnan(y) & ~isnan(z) & ~isnan(u) & ~isnan(v) & ~isnan(w));
+x=x(pos); y=y(pos); z=z(pos);
+u=u(pos); v=v(pos); w=w(pos);
+
+%get norm Min and Max
+Norm=sqrt(u.^2+v.^2+w.^2);
+Min=min(Norm);
+Max=max(Norm);
+
+%process options: scaling factor?
+scalingfactor=getfieldvalue(options,'scaling',0.40);
+
+%number of colors?
+colorlevels=getfieldvalue(options,'colorlevels',NaN);
+if isnumeric(colorlevels),
+	if isnan(colorlevels),
+		numcolors=30;
+	else
+		numcolors=colorlevels;
+	end
+	levels=round_ice(linspace(Min,Max,numcolors+1),2);
+else
+	levels=zeros(1,length(colorlevels)+2);
+	levels(1)=Min;
+	for i=1:length(colorlevels)
+		levels(i+1)=colorlevels{i};
+	end
+	levels(end)=Max;
+	levels=sort(unique(levels));
+	numcolors=length(levels)-1;
+end
+
+%set the colormap 
+if numcolors==2;
+	%blue and red
+	c=[0 0 1;1 0 0];
+elseif numcolors==3,
+	%blue yellow and red
+	c=[0 0 1;1 1 0;1 0 0];
+else
+	%let jet choose
+	c=colormap(jet(numcolors));
+end
+
+%Scale data
+if strcmpi(getfieldvalue(options,'autoscale','on'),'off'),
+	delta=((min(x)-max(x))^2+(min(y)-max(y))^2)/numel(x);
+	u=scalingfactor*sqrt(delta)*u./Norm;
+	v=scalingfactor*sqrt(delta)*v./Norm;
+else
+	delta=((min(x)-max(x))^2+(min(y)-max(y))^2)/numel(x);
+	u=scalingfactor*sqrt(delta)*u./max(Norm);
+	v=scalingfactor*sqrt(delta)*v./max(Norm);
+end
+
+%loop over the number of colors
+hold on
+h=[];
+for i=1:numcolors
+	pos=find( (Norm>=levels(i)) & (Norm<=levels(i+1)) );
+	hprime=quiver3(x(pos),y(pos),z(pos),u(pos),v(pos),w(pos),'Color',c(i,:),'ShowArrowHead','on','AutoScale','off');
+	h=[h;hprime];
+end
+
+%take care of colorbar
+if  ~strcmpi(getfieldvalue(options,'colorbar','on'),'off'),
+
+	%build ticks
+	hcb=colorbar('peer',gca,'location','EastOutside');
+	ticklabel=cell(1,length(levels));
+	for i=1:length(levels),
+		ticklabel{i}=num2str(round_ice(levels(i),3));
+	end
+	tickpos=1:numcolors+1;
+
+	%remove ticks if to many have been created
+	proportion=round(length(levels)/10);
+	if proportion>1,
+		ticklabel=ticklabel(1:proportion:end);
+		tickpos=tickpos(1:proportion:end);
+	end
+
+	%draw colorbar
+	set(hcb,'YTickLabel',ticklabel,'YTick',tickpos);
+	%position
+	if exist(options,'colorbarpos'),
+		set(hcb,'Position',getfieldvalue(options,'colorbarpos'));
+	end
+	%fontsize
+	fontsize=getfieldvalue(options,'fontsize',14);
+	set(hcb,'FontSize',fontsize);
+end
Index: /issm/trunk/src/m/model/plot/plot_riftfraction.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_riftfraction.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_riftfraction.m	(revision 5901)
@@ -0,0 +1,52 @@
+function plot_riftfraction(md,options,nlines,ncols,index);
+%PLOT_RIFTFRACTION - plot rift fractions
+%
+%   Usage:
+%      plot_riftfraction(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%check that there is something in riftproperties
+if isnan(md.riftproperties),
+	error('plot_riftfraction error message: field riftproperies is empty, run the model first')
+end
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+
+subplot(nlines,ncols,index); 
+hold on
+
+%plot mesh boundaries
+for i=1:size(md.segments,1),
+	h1=plot(x(md.segments(i,1:2)),y(md.segments(i,1:2)),'k.-');
+end
+
+%first, build a vector of fractions, over all grids. 
+fractions=zeros(md.numberofgrids,1);
+
+%plug riftproperties fractions:
+fractions(md.riftinfo(:,1))=md.riftproperties;
+fractions(md.riftinfo(:,2))=md.riftproperties;
+
+%complete the tips.
+for i=1:length(md.rifts), 
+	tips=md.rifts(i).tips;
+	fractions(tips)=1;
+end
+
+hold on;
+for i=1:length(md.rifts), 
+	segments=md.rifts(i).segments(:,1:2)';
+	xc=x(segments(:));
+	yc=y(segments(:));
+	zc=fractions(segments(:));
+	h2=patch('Xdata',xc,'Ydata',yc,'Zdata',zc,'Cdata',zc,'facecolor','none','edgecolor','flat');
+end
+legend([h1,h2],'mesh boundaries','rifts')
+hold off
+
+%apply options
+options=addfielddefault(options,'title','Rift ice/water fraction ???????'); %Eric, could you enter a better title?
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_riftpenetration.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_riftpenetration.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_riftpenetration.m	(revision 5901)
@@ -0,0 +1,77 @@
+function plot_rifpenetration(md,options,nlines,ncols,index);
+%PLOT_RIFTPENETRATION - plot rift penetration
+%
+%   Usage:
+%      plot_rifpenetration(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+
+subplot(nlines,ncols,index); 
+hold on
+
+%plot mesh boundaries
+for i=1:size(md.segments,1),
+	plot(x(md.segments(i,1:2)),y(md.segments(i,1:2)),'k.-');
+end
+
+isp1=0;
+isp2=0;
+
+if isstruct(md.rifts),
+	%plot mesh boundaries
+	for i=1:size(md.segments,1),
+		h1=plot(x(md.segments(i,1:2)),y(md.segments(i,1:2)),'b-');
+	end
+	for i=1:size(md.rifts,1),
+		penaltypairs=md.rifts(i).penaltypairs;
+
+		segments=md.rifts(i).segments;
+		for j=1:size(segments,1),
+			plot(x(segments(j,1:2)),y(segments(j,1:2)),'b-');
+		end
+
+		normal=zeros(2,1);
+		for j=1:size(penaltypairs,1),
+			normal(1)=penaltypairs(j,5);
+			normal(2)=penaltypairs(j,6);
+
+			vx1=md.vx(penaltypairs(j,1)); 
+			vx2=md.vx(penaltypairs(j,2));
+			vy1=md.vy(penaltypairs(j,1)); 
+			vy2=md.vy(penaltypairs(j,2));
+			penetration=(vx2-vx1)*normal(1)+(vy2-vy1)*normal(2);
+			%if penetration is negative, plot in black, positive, plot in red;: ie: if rift is closing, black, if rift is opening, red.
+			if(penetration>0),
+				p2=plot(x(penaltypairs(j,1)) ,y(penaltypairs(j,1)),'r*');
+				isp2=1;
+			else
+				p1=plot(x(penaltypairs(j,1)) ,y(penaltypairs(j,1)),'k*');
+				isp1=1;
+			end
+		end
+
+		%point out the tips
+		h2=plot(x(md.rifts(i).tips(1)),y(md.rifts(i).tips(1)),'g*');
+		plot(x(md.rifts(i).tips(2)),y(md.rifts(i).tips(2)),'g*');
+	end
+	if isp1 & isp2
+		legend([h1,h2,p1,p2],'mesh boundaries','rift tips',' rifts closing','rifts opening')
+	elseif isp1
+		legend([h1,h2,p1],'mesh boundaries','rift tips',' rifts closing')
+	elseif isp2
+		legend([h1,h2,p2],'mesh boundaries','rift tips','rifts opening')
+	else
+		legend([h1,h2],'mesh boundaries','rift tips')
+	end
+else
+	error('plot error message: no rifts available!');
+end
+hold off
+
+%apply options
+options=addfielddefault(options,'title','Rift Penetration');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_riftrelvel.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_riftrelvel.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_riftrelvel.m	(revision 5901)
@@ -0,0 +1,108 @@
+function plot_riftrelvel(md,options,nlines,ncols,index);
+%PLOT_RIFTRELVEL - plot rift relative velocities
+%
+%   Usage:
+%      plot_riftrelvel(md,options,nlines,ncols,i);
+%
+%   See also: PLOTMODEL
+
+%some checks
+if (length(md.vx)~=md.numberofgrids | length(md.vy)~=md.numberofgrids),
+	error('plot_riftvel error message: vx and vy do not have the right size'),
+end
+if ~isstruct(md.rifts),
+	error('plot error message: no rifts available!');
+end
+options=addfielddefault(options,'scaling',2);
+
+%set as NaN all velocities not on rifts
+u=NaN*ones(md.numberofgrids,1);
+v=NaN*ones(md.numberofgrids,1);
+for i=1:md.numrifts,
+	penaltypairs=md.rifts(i).penaltypairs(:,[1 2]);
+	u(md.rifts(i).penaltypairs(:,1))=md.vx(penaltypairs(:,1))-md.vx(penaltypairs(:,2));
+	v(md.rifts(i).penaltypairs(:,1))=md.vy(penaltypairs(:,1))-md.vy(penaltypairs(:,2));
+end
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+[vel datatype]=processdata(md,[u v],options);
+[quivers,palette]=quiver_process(x,y,vel(:,1),vel(:,2),options);
+
+%prepare plot
+subplot(nlines,ncols,index); 
+hold on
+
+%plot mesh boundaries
+for i=1:size(md.segments,1),
+	plot(x(md.segments(i,1:2)),y(md.segments(i,1:2)),'k.-');
+end
+
+%plot rifts vel
+h3=[];
+for i=1:quivers.numcolors
+	pos=find(quivers.colorind==i);
+	hprime=quiver(quivers.x(pos),quivers.y(pos),quivers.u(pos),quivers.v(pos),...
+		'Color',palette(i,:),'ShowArrowHead','on','AutoScale','off');
+	hprime=quiver(quivers.x(pos),quivers.y(pos),-quivers.u(pos),-quivers.v(pos),...
+		'Color',palette(i,:),'ShowArrowHead','on','AutoScale','off');
+	h3=[h3;hprime];
+end
+
+%plot rift velocities
+isp1=0;
+isp2=0;
+
+%plot mesh boundaries
+for i=1:size(md.segments,1),
+	h1=plot(x(md.segments(i,1:2)),y(md.segments(i,1:2)),'b-');
+end
+for i=1:md.numrifts,
+	
+	%get grids on rift
+	penaltypairs=md.rifts(i).penaltypairs;
+
+	segments=md.rifts(i).segments;
+	for j=1:size(segments,1),
+		plot(x(segments(j,1:2)),y(segments(j,1:2)),'b-');
+	end
+
+	normal=zeros(2,1);
+	for j=1:size(penaltypairs,1),
+		normal(1)=penaltypairs(j,5);
+		normal(2)=penaltypairs(j,6);
+
+		vx1=md.vx(penaltypairs(j,1)); vx2=md.vx(penaltypairs(j,2)); vy1=md.vy(penaltypairs(j,1)); vy2=md.vy(penaltypairs(j,2));
+		penetration=(vx2-vx1)*normal(1)+(vy2-vy1)*normal(2);
+		%if penetration is negative, plot in black, positive, plot in red;: ie: if rift is closing, black, if rift is opening, red.
+		if(penetration>0),
+			p2=plot(x(penaltypairs(j,1)) ,y(penaltypairs(j,1)),'*'); set(p2,'Color',[140 140 140]/255);
+			isp2=1;
+		else
+			p1=plot(x(penaltypairs(j,1)) ,y(penaltypairs(j,1)),'k*');
+			isp1=1;
+		end
+	end
+
+	%point out the tips
+	h2=plot(x(md.rifts(i).tips(1)),y(md.rifts(i).tips(1)),'g*');
+	plot(x(md.rifts(i).tips(2)),y(md.rifts(i).tips(2)),'g*');
+	segments=md.rifts(i).segments(:,1:2);
+end
+%legend
+if isp1 & isp2
+	legend([h1,h2,p1,p2],'mesh boundaries','rift tips',' rifts closing','rifts opening')
+elseif isp1
+	legend([h1,h2,p1],'mesh boundaries','rift tips',' rifts closing')
+elseif isp2
+	legend([h1,h2,p2],'mesh boundaries','rift tips','rifts opening')
+else
+	legend([h1,h2],'mesh boundaries','rift tips')
+end
+hold off
+
+%apply options
+quiver_colorbar(quivers,options);
+options=changefieldvalue(options,'colorbar',2);
+options=addfielddefault(options,'title','Rift Relative Velocities');
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_rifts.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_rifts.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_rifts.m	(revision 5901)
@@ -0,0 +1,77 @@
+function plot_rifts(md,options,nlines,ncols,index);
+%PLOT_RIFTS - plot rifts in a mesh
+%
+%   Usage:
+%      plot_rifts(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+
+%plot mesh
+subplot(nlines,ncols,index); 
+
+%offset to separate rift flanks.
+offset=getfieldvalue(options,'offset',500);
+if isstruct(md.rifts),
+	
+	for i=1:md.numrifts,
+		penaltypairs=md.rifts(i).penaltypairs;
+
+		normal=zeros(2,1);
+		for j=1:size(penaltypairs,1),
+			normal(1)=penaltypairs(j,5);
+			normal(2)=penaltypairs(j,6);
+			x(penaltypairs(j,1))=x(penaltypairs(j,1))-normal(1)*offset;
+			y(penaltypairs(j,1))=y(penaltypairs(j,1))-normal(2)*offset;
+		end
+		if length(md.rifts(i).tips)==3,
+			tip=md.rifts(i).tips(3);
+			%who is tip connected to? 
+			if isconnected(md.elements,penaltypairs(1,1),tip),
+				normal(1)=penaltypairs(1,5);
+				normal(2)=penaltypairs(1,6);
+				x(tip)=x(tip)-normal(1)*offset;
+				y(tip)=y(tip)-normal(2)*offset;
+			end
+
+			if isconnected(md.elements,penaltypairs(1,2),tip),
+				normal(1)=penaltypairs(1,5);
+				normal(2)=penaltypairs(1,6);
+				x(tip)=x(tip)+normal(1)*offset;
+				y(tip)=y(tip)+normal(2)*offset;
+			end
+			if isconnected(md.elements,penaltypairs(end,1),tip),
+				normal(1)=penaltypairs(end,5);
+				normal(2)=penaltypairs(end,6);
+				x(tip)=x(tip)-normal(1)*offset;
+				y(tip)=y(tip)-normal(2)*offset;
+			end
+			if isconnected(md.elements,penaltypairs(end,2),tip),
+				normal(1)=penaltypairs(end,5);
+				normal(2)=penaltypairs(end,6);
+				x(tip)=x(tip)+normal(1)*offset;
+				y(tip)=y(tip)+normal(2)*offset;
+			end
+		end
+	end
+end
+
+%plot mesh
+if is2d
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); 
+	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+else
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+	patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [D E F], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [A B E D], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [B E F C ], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	patch( 'Faces', [C A D F ], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+end
+
+%apply options
+options=addfielddefault(options,'title','Rifts');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_riftvel.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_riftvel.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_riftvel.m	(revision 5901)
@@ -0,0 +1,108 @@
+function plot_riftvel(md,options,nlines,ncols,index);
+%PLOT_RIFTVEL - plot rift velocity
+%
+%   Usage:
+%      plot_riftvel(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%some checks
+if (length(md.vx)~=md.numberofgrids | length(md.vy)~=md.numberofgrids),
+	error('plot_riftvel error message: vx and vy do not have the right size'),
+end
+if ~isstruct(md.rifts),
+	error('plot error message: no rifts available!');
+end
+options=addfielddefault(options,'scaling',2);
+
+%set as NaN all velocities not on rifts
+u=NaN*ones(md.numberofgrids,1);
+v=NaN*ones(md.numberofgrids,1);
+for i=1:md.numrifts,
+	penaltypairs=md.rifts(i).penaltypairs(:,[1 2]);
+	u(penaltypairs(:))=md.vx(penaltypairs(:));
+	v(penaltypairs(:))=md.vy(penaltypairs(:));
+end
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+[vel datatype]=processdata(md,[u v],options);
+[quivers,palette]=quiver_process(x,y,vel(:,1),vel(:,2),options);
+
+%prepare plot
+subplot(nlines,ncols,index); 
+hold on
+
+%plot mesh boundaries
+for i=1:size(md.segments,1),
+	plot(x(md.segments(i,1:2)),y(md.segments(i,1:2)),'k.-');
+end
+
+%plot rifts vel
+h3=[];
+for i=1:quivers.numcolors
+	pos=find(quivers.colorind==i);
+	hprime=quiver(quivers.x(pos),quivers.y(pos),quivers.u(pos),quivers.v(pos),...
+		'Color',palette(i,:),'ShowArrowHead','on','AutoScale','off');
+	h3=[h3;hprime];
+end
+
+%plot rift velocities
+isp1=0;
+isp2=0;
+
+%plot mesh boundaries
+for i=1:size(md.segments,1),
+	h1=plot(x(md.segments(i,1:2)),y(md.segments(i,1:2)),'b-');
+end
+
+for i=1:size(md.rifts,1),
+	%get grids on rift
+	penaltypairs=md.rifts(i).penaltypairs;
+
+	segments=md.rifts(i).segments;
+	for j=1:size(segments,1),
+		plot(x(segments(j,1:2)),y(segments(j,1:2)),'b-');
+	end
+
+	normal=zeros(2,1);
+	for j=1:size(penaltypairs,1),
+		normal(1)=penaltypairs(j,5);
+		normal(2)=penaltypairs(j,6);
+
+		vx1=md.vx(penaltypairs(j,1)); vx2=md.vx(penaltypairs(j,2)); vy1=md.vy(penaltypairs(j,1)); vy2=md.vy(penaltypairs(j,2));
+		penetration=(vx2-vx1)*normal(1)+(vy2-vy1)*normal(2);
+		%if penetration is negative, plot in black, positive, plot in red;: ie: if rift is closing, black, if rift is opening, red.
+		if(penetration>0),
+			p2=plot(x(penaltypairs(j,1)) ,y(penaltypairs(j,1)),'*'); set(p2,'Color',[140 140 140]/255);
+			isp2=1;
+		else
+			p1=plot(x(penaltypairs(j,1)) ,y(penaltypairs(j,1)),'k*');
+			isp1=1;
+		end
+	end
+
+	%point out the tips
+	h2=plot(x(md.rifts(i).tips(1)),y(md.rifts(i).tips(1)),'g*');
+	plot(x(md.rifts(i).tips(2)),y(md.rifts(i).tips(2)),'g*');
+	segments=md.rifts(i).segments(:,1:2);
+end
+
+
+%legend
+if isp1 & isp2
+	legend([h1,h2,p1,p2],'mesh boundaries','rift tips',' rifts closing','rifts opening')
+elseif isp1
+	legend([h1,h2,p1],'mesh boundaries','rift tips',' rifts closing')
+elseif isp2
+	legend([h1,h2,p2],'mesh boundaries','rift tips','rifts opening')
+else
+	legend([h1,h2],'mesh boundaries','rift tips')
+end
+hold off
+
+%apply options
+quiver_colorbar(quivers,options);
+options=changefieldvalue(options,'colorbar',2);
+options=addfielddefault(options,'title','Rift Velocities');
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_sarpwr.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_sarpwr.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_sarpwr.m	(revision 5901)
@@ -0,0 +1,26 @@
+function plot_sarpwr(md,options,width,i);
+%PLOT_SARPWR - plot radar image
+%
+%   Usage:
+%      plot_sarpwr(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%plot mesh sarpwr
+subplot(width,width,i); 
+
+%units
+if exist(options,'unit'),
+	unit=getfieldvalue(options,'unit');
+	md.x=md.x*unit;
+	md.y=md.y*unit;
+	md.z=md.z*unit;
+end
+					
+imagesc(md.sarxm,md.sarym,double(md.sarpwr)),set(gca,'YDir','normal');colormap(gray);
+
+%apply options
+options=addfielddefault(options,'colorbar',0);
+options=changefieldvalue(options,'colormap','gray');
+
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_section.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_section.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_section.m	(revision 5901)
@@ -0,0 +1,200 @@
+function plot_section(md,data,options,nlines,ncols,i)
+%PLOT_SECTION - plot a given field on a section
+%
+%   Usage:
+%      plot_section(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%How many subplots?
+if exist(options,'showsection')
+
+	%Compute the indexes of the 2 plots (one for the sectionvalue and one for showsection
+	upperplots=fix((i-1)/width);
+	if upperplots==0, leftplots=i-1; else leftplots=i-width*upperplots-1; end
+	index1=4*width*upperplots+2*leftplots+1;
+	index2=index1+1;
+	width=2*width;
+else
+	index1=i;
+end
+
+%process model
+[x_m y_m z_m elements_m is2d]=processmesh(md,[],options);
+
+%Get number of curves and generate random colors
+numcurves=size(data,2);
+colorm=getfieldvalue(options,'colormap','jet');
+options=changefieldvalue(options,'colormap','jet');
+eval(['color=' colorm '(numcurves);']);
+
+%Loop over number of curves
+for i=1:numcurves,
+
+	[datai datatype]=processdata(md,data(:,i),options);
+
+	%replug x and y onto model so that SectionValue treats the problem correctly
+	if exist(options,'layer')
+		md.x=md.x2d; md.y=md.y2d; md.elements=md.elements2d; md.dim=2;
+	end
+
+	%resolution
+	if exist(options,'resolution'),
+		resolution=getfieldvalue(options,'resolution');
+	else %Default resolution
+		resolution=[1000 10*md.numlayers];
+		disp(['plot_section warning: no resolution specified, use default resolution: [horizontal_resolution vertical_resolution]=[' num2str(resolution)  ']']);
+	end
+
+	%Compute section value
+	[elements,x,y,z,s,data_s]=SectionValues(md,datai,getfieldvalue(options,'sectionvalue'),resolution);
+
+	%units
+	if exist(options,'unit'),
+		unit=getfieldvalue(options,'unit');
+		x=x*unit;
+		y=y*unit;
+		z=z*unit;
+		s=s*unit;
+	end
+
+	%2D
+	if is2d
+
+		%Show Section if requested by user
+		if exist(options,'showsection')
+
+			%compute number of labels
+			numlabels=min(getfieldvalue(options,'showsection'),length(s));
+			shift=fix(length(s)/numlabels);
+
+			%plot labels on current graph
+			hold on
+			text(s(1),data_s(1),'1','backgroundcolor',[0.8 0.9 0.8])
+			for i=2:numlabels-1
+				text(s(1+(i-1)*shift),data_s(1+(i-1)*shift),num2str(i),'backgroundcolor',[0.8 0.9 0.8])
+			end
+			text(s(end),data_s(end),'end','backgroundcolor',[0.8 0.9 0.8])
+
+			%plot section only with labels
+			subplot(width,width,index2)
+			plot_unit(x_m,y_m,z_m,elements_m,data(:,i),is2d,datatype,options)
+			hold on
+			text(x(1),y(1),'1','backgroundcolor',[0.8 0.9 0.8])
+			for i=2:numlabels-1
+				text(x(1+(i-1)*shift),y(1+(i-1)*shift),num2str(i),'backgroundcolor',[0.8 0.9 0.8])
+			end
+			text(x(end),y(end),'end','backgroundcolor',[0.8 0.9 0.8])
+			plot(x,y,'-r')
+			axis([min(md.x)-1 max(md.x)+1 min(md.y)-1 max(md.y)+1])
+			view(2)
+		end
+
+		%plot section value
+		hold on;
+		subplot(nlines,ncols,index1)
+		%subplot(1,3,[2 3])
+		if i==1,
+			plot(s,data_s,'-.','color',color(i+1,:),'LineWidth',getfieldvalue(options,'linewidth',1))
+		elseif i==2
+			plot(s,data_s,'-.','color',color(i+1,:),'LineWidth',getfieldvalue(options,'linewidth',1))
+		elseif i==3
+			plot(s,data_s,'--','color',color(i+1,:),'LineWidth',getfieldvalue(options,'linewidth',1))
+		elseif i==4
+			plot(s,data_s,'-','color',color(i+1,:),'LineWidth',getfieldvalue(options,'linewidth',1))
+		elseif i==5
+			plot(s,data_s,'-','color','k','LineWidth',getfieldvalue(options,'linewidth',1))
+		end
+
+		%3D
+	else
+		%plot section value
+		%if user requested view2: 2d plot with curvilinear coordinate
+		if (getfieldvalue(options,'view',3)==2 )
+
+			%Show Section if requested by user
+			if exist(options,'showsection')
+
+				%compute number of labels
+				numlabels=min(getfieldvalue(options,'showsection'),length(s));
+				shift=fix(length(s)/numlabels);
+
+				%plot labels on current graph
+				hold on
+				text(s(1),z(1),'1','backgroundcolor',[0.8 0.9 0.8])
+				for i=2:numlabels-1
+					text(s(1+(i-1)*shift),z(1+(i-1)*shift),num2str(i),'backgroundcolor',[0.8 0.9 0.8])
+				end
+				text(s(end),z(end),'end','backgroundcolor',[0.8 0.9 0.8])
+
+				%plot section only with labels
+				subplot(width,width,index2)
+				plot_unit(x_m,y_m,z_m,elements_m,data(:,i),is2d,datatype,options)
+				hold on
+				text(x(1),y(1),'1','backgroundcolor',[0.8 0.9 0.8])
+				for i=2:numlabels-1
+					text(x(1+(i-1)*shift),y(1+(i-1)*shift),num2str(i),'backgroundcolor',[0.8 0.9 0.8])
+				end
+				text(x(end),y(end),'end','backgroundcolor',[0.8 0.9 0.8])
+				plot(x,y,'-r')
+				axis([min(md.x)-1 max(md.x)+1 min(md.y)-1 max(md.y)+1])
+				view(2)
+			end
+
+			subplot(width,width,index1)
+			A=elements(:,1); B=elements(:,2); C=elements(:,3);  D=elements(:,4); 
+			patch( 'Faces', [A B C D], 'Vertices', [s z zeros(length(s),1)],'FaceVertexCData',data_s,'FaceColor','interp','EdgeColor','none');
+
+		else
+
+			%Show Section if requested by user
+			if exist(options,'showsection')
+
+				%compute number of labels
+				numlabels=min(getfieldvalue(options,'showsection'),length(s));
+				shift=fix(length(x)/numlabels);
+
+				%plot labels on current graph
+				hold on
+				text(x(1),y(1),z(1),'1','backgroundcolor',[0.8 0.9 0.8])
+				for i=2:numlabels-1
+					text(x(1+(i-1)*shift),y(1+(i-1)*shift),z(1+(i-1)*shift),num2str(i),'backgroundcolor',[0.8 0.9 0.8])
+				end
+				text(x(end),y(end),z(end),'end','backgroundcolor',[0.8 0.9 0.8])
+
+				%plot section only with labels
+				subplot(width,width,index2)
+				plot_unit(x_m,y_m,z_m,elements_m,data,is2d,datatype,options)
+				hold on
+				text(x(1),y(1),'1','backgroundcolor',[0.8 0.9 0.8])
+				for i=2:numlabels-1
+					text(x(1+(i-1)*shift),y(1+(i-1)*shift),num2str(i),'backgroundcolor',[0.8 0.9 0.8])
+				end
+				text(x(end),y(end),'end','backgroundcolor',[0.8 0.9 0.8])
+				plot(x,y,'-r')
+				axis([min(md.x)-1 max(md.x)+1 min(md.y)-1 max(md.y)+1])
+				view(2)
+			end
+
+			subplot(width,width,index1)
+			A=elements(:,1); B=elements(:,2); C=elements(:,3);  D=elements(:,4); 
+			patch( 'Faces', [A B C D], 'Vertices', [x y z],'FaceVertexCData',data_s,'FaceColor','interp','EdgeColor','none');
+			view(3)
+
+		end
+	end
+end
+
+%apply options
+options=addfielddefault(options,'title','Section value');
+if (md.dim==2)
+	options=addfielddefault(options,'colorbar',0);
+end
+if ((md.dim==2) | getfieldvalue(options,'view')==2 )
+	options=addfielddefault(options,'xlabel','Curvilinear coordinate');
+	options=addfielddefault(options,'axis','auto');
+end
+if (md.dim==3 & getfieldvalue(options,'view')==2 )
+	options=addfielddefault(options,'ylabel','z');
+end
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_segments.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_segments.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_segments.m	(revision 5901)
@@ -0,0 +1,57 @@
+function plot_segments(md,options,width,i,datai);
+%PLOT_SEGMENTS - plot segments, with different colors according to segment markers.
+%
+%   Usage:
+%      plot_segments(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%plot mesh boundaries
+subplot(width,width,i); 
+
+%process mesh and data
+[x y z elements is2d]=processmesh(md,[],options);
+segments=md.segments;
+
+if (md.dim==2),
+	%plot mesh
+	A=elements(:,1); B=elements(:,2); C=elements(:,3); 
+	h1=patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','none','EdgeColor','black');
+	hold on;
+
+	%highlight elements on neumann
+	pos=segments(:,end);
+	A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); 
+	h2=patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', [1 1 1],'FaceColor','green','EdgeColor','black');
+
+	if strcmpi(getfieldvalue(options,'segmentnumbering','off'),'on'),
+		text(sum(x(segments(:,1:2)),2)/2,sum(y(segments(:,1:2)),2)/2,sum(z(segments(:,1:2)),2)/2+1,...
+			num2str(md.segmentmarkers),...
+			'backgroundcolor',[0.8 0.9 0.8],'HorizontalAlignment','center','VerticalAlignment','middle');
+	end
+
+	%display arrows pointing outward
+	xstart=mean(x(segments(:,1:end-1)),2);
+	ystart=mean(y(segments(:,1:end-1)),2);
+	length=sqrt((x(segments(:,1))-x(segments(:,2))).^2 + (y(segments(:,1))-y(segments(:,2))).^2 );
+	normal(:,1)=cos(atan2((x(segments(:,1))-x(segments(:,2))) , (y(segments(:,2))-y(segments(:,1)))));
+	normal(:,2)=sin(atan2((x(segments(:,1))-x(segments(:,2))) , (y(segments(:,2))-y(segments(:,1)))));
+	xend=xstart+length.*normal(:,1);
+	yend=ystart+length.*normal(:,2);
+	q=quiver(xstart,ystart,xend-xstart,yend-ystart); hold on;
+	h3=plot(xstart,ystart,'r*');
+
+
+else
+	error('plot_segments: 3d plot of segments not supported yet!');
+end
+
+%legend (disable warnings)
+warning off
+legend([h2,q],'element on segment','normal vectors')
+warning on
+
+%apply options
+options=addfielddefault(options,'title','Segment boundaries');
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_streamlines.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_streamlines.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_streamlines.m	(revision 5901)
@@ -0,0 +1,41 @@
+function plot_streamlines(md,options)
+%PLOT_STREAMLINES - plot stream lines on a figure
+%
+%   Usage:
+%      plot_streamlines(md,options)
+
+%process data and model
+[x y z index is2d]=processmesh(md,[],options);
+[u datatype]=processdata(md,md.vx,options);
+[v datatype]=processdata(md,md.vy,options);
+
+%some checks
+if ~is2d,
+	disp('plot_streamlines error: streamlines option not supported for 3d plots. Project on a layer')
+	return
+end
+
+%initialize flowpath
+streamlines=getfieldvalue(options,'streamlines');
+if ischar(streamlines) & strcmpi(streamlines,'on');
+	streamlines=60;
+end
+if iscell(streamlines)
+	x0=[]; y0=[];
+	for i=1:size(streamlines,2)
+		coord=streamlines{i};
+		x0=[x0;coord(1)]; y0=[y0;coord(2)];
+	end
+else
+	x0=x(1:ceil(length(x)/streamlines):end);
+	y0=y(1:ceil(length(x)/streamlines):end);
+end
+
+%Get flow lines
+flowpath=flowlines(index,x,y,u,v,x0,y0);
+
+%plot
+hold on
+for i=1:length(flowpath)
+	patch('Xdata',[flowpath(i).x;NaN],'Ydata',[flowpath(i).y;NaN],'facecolor','none','edgecolor','y');
+end
Index: /issm/trunk/src/m/model/plot/plot_tensor.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_tensor.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_tensor.m	(revision 5901)
@@ -0,0 +1,39 @@
+function plot_tensor(md,options,width,i,type);
+%PLOT_TENSOR - plot tensor components
+%
+%   Usage:
+%      plot_tensor(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+h=subplot(width,width,i); axis off; pos=get(h,'Position');
+
+plot_options.offsetx=pos(1);
+plot_options.offsety=pos(2);
+plot_options.width=pos(3);
+plot_options.height=pos(4);
+
+%Figure out tensor type:
+if strncmpi(type,'strain',6),
+	tensor=md.strainrate;
+elseif strncmpi(type,'stress',6),
+	tensor=md.stress;
+elseif strncmpi(type,'deviatoricstress',16),
+	tensor=md.deviatoricstress;
+else
+	error('plot_tensor error message: unsupported type of tensor');
+end
+
+%Figure out type of plot being requested
+if strncmpi(fliplr(type),fliplr('tensor'),6) | strcmpi(type,'strainrate') | strcmpi(type,'deviatoricstress') | strcmpi(type,'stress'),
+	plot_tensor_components(md,options,width,i,tensor,type,plot_options);
+	return;
+elseif strncmpi(fliplr(type),fliplr('principal'),9),
+	plot_tensor_principal(md,options,width,i,tensor,type,plot_options);
+	return;
+elseif strncmpi(fliplr(type(1:end-1)),fliplr('principalaxis'),13),
+	plot_tensor_principalaxis(md,options,width,i,tensor,type,plot_options);
+	return;
+else
+	error('plot_tensor error message: unsurported type of plot');
+end
Index: /issm/trunk/src/m/model/plot/plot_tensor_components.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_tensor_components.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_tensor_components.m	(revision 5901)
@@ -0,0 +1,78 @@
+function plot_tensor_components(md,options,width,i,tensor,type,plot_options);
+%PLOT_TENSOR_COMPONENT - plot component of a tensor
+%
+%   Usage:
+%      plot_tensor_components(md,options,width,i,tensor,type,plot_option);
+%
+%   See also: PLOTMODEL, PLOT_UNIT, PLOT_MANAGER
+
+%Compute the indexes of the components plots
+upperplots=fix((i-1)/width);
+if upperplots==0, leftplots=i-1; else leftplots=i-width*upperplots-1; end
+if (md.dim==2)%3 components -> 3 indexes
+	index1=4*width*upperplots+2*leftplots+1;
+	index2=index1+1;
+	index3=index1+width*2;
+elseif md.dim==3%6 components -> 6 indexes
+	index1=3*3*width*upperplots+3*leftplots+1;
+	index2=index1+1;
+	index3=index1+2;
+	index4=index1+width*3;
+	index5=index4+1;
+	index6=index4+2;
+end
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+[tensor.xx datatype]=processdata(md,tensor.xx,options);
+[tensor.yy datatype]=processdata(md,tensor.yy,options);
+[tensor.xy datatype]=processdata(md,tensor.xy,options);
+if  md.dim==3
+	[tensor.xz datatype]=processdata(md,tensor.xz,options);
+	[tensor.yz datatype]=processdata(md,tensor.yz,options);
+	[tensor.zz datatype]=processdata(md,tensor.zz,options);
+end
+
+if ((md.dim==2)),
+	subplot(2*width,2*width,index1),
+	plot_unit(x,y,z,elements,tensor.xx,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'xx')
+	subplot(2*width,2*width,index2),
+	plot_unit(x,y,z,elements,tensor.yy,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'yy')
+	subplot(2*width,2*width,index3),
+	plot_unit(x,y,z,elements,tensor.xy,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'xy')
+else
+	subplot(3*width,3*width,index1),
+	plot_unit(x,y,z,elements,tensor.xx,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'xx')
+	subplot(3*width,3*width,index2),
+	plot_unit(x,y,z,elements,tensor.yy,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'yy')
+	subplot(3*width,3*width,index3),
+	plot_unit(x,y,z,elements,tensor.zz,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'zz')
+	subplot(3*width,3*width,index4),
+	plot_unit(x,y,z,elements,tensor.xy,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'xy')
+	subplot(3*width,3*width,index5),
+	plot_unit(x,y,z,elements,tensor.xz,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'xz')
+	subplot(3*width,3*width,index6),
+	plot_unit(x,y,z,elements,tensor.yz,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'yz')
+end
+end
+
+function Apply_options_tensor(md,options,type,component)
+	%apply options
+	if ismember('_',type) %user plotet stress_tensor
+		strings=strsplit(type,'_');
+		string=strings{1};
+	else %default plot: user requested stress
+		string=type;
+	end
+	options=addfielddefault(options,'title',[upper(string(1)) string(2:end) ' ' component]);
+	applyoptions(md,[],options);
+end
Index: /issm/trunk/src/m/model/plot/plot_tensor_principal.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_tensor_principal.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_tensor_principal.m	(revision 5901)
@@ -0,0 +1,77 @@
+function plot_tensor_principal(md,options,width,i,tensor,type,plot_options);
+%PLOT_TENSOR_PRINCIPAL - plot principal values
+%
+%   Usage:
+%      plot_tensor_principal(md,options,width,i,tensor,type,plot_options);
+%
+%   See also: PLOTMODEL, PLOT_UNIT, PLOT_MANAGER
+
+%Compute the indexes of the components plots
+upperplots=fix((i-1)/width);
+if upperplots==0, leftplots=i-1; else leftplots=i-width*upperplots-1; end
+if (md.dim==2)%3 components -> 3 indexes
+	index1=4*width*upperplots+2*leftplots+1;
+	index2=index1+1;
+	index3=index1+width*2;
+	index4=index3+1;
+	newwidth=2*width;
+elseif md.dim==3%6 components -> 6 indexes
+	index1=3*3*width*upperplots+3*leftplots+1;
+	index2=index1+1;
+	index3=index1+2;
+	index4=index1+width*3;
+	index5=index4+1;
+	index6=index4+2;
+	newwidth=3*width;
+end
+
+%plot principal axis
+type1=[type 'axis1'];
+plot_tensor_principalaxis(md,options,newwidth,index1,tensor,type1,plot_options);
+type2=[type 'axis2'];
+plot_tensor_principalaxis(md,options,newwidth,index2,tensor,type2,plot_options);
+if  md.dim==3
+	type3=[type 'axis3'];
+	plot_tensor_principalaxis(md,options,newwidth,index3,tensor,type3,plot_options);
+end
+
+%now plot principal values
+[x y z elements is2d]=processmesh(md,[],options);
+[tensor.principalvalue1 datatype]=processdata(md,tensor.principalvalue1,options);
+[tensor.principalvalue2 datatype]=processdata(md,tensor.principalvalue2,options);
+if  md.dim==3
+	[tensor.principalvalue3 datatype]=processdata(md,tensor.principalvalue3,options);
+end
+
+if ((md.dim==2)),
+	subplot(2*width,2*width,index3)
+	plot_unit(x,y,z,elements,tensor.principalvalue1,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'principal value 1')
+	subplot(2*width,2*width,index4)
+	plot_unit(x,y,z,elements,tensor.principalvalue2,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'principal value 2')
+else
+	subplot(3*width,3*width,index4)
+	plot_unit(x,y,z,elements,tensor.principalvalue1,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'principal value 1')
+	subplot(3*width,3*width,index5)
+	plot_unit(x,y,z,elements,tensor.principalvalue2,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'principal value 2')
+	subplot(3*width,3*width,index6)
+	plot_unit(x,y,z,elements,tensor.principalvalue3,is2d,datatype,options)
+	Apply_options_tensor(md,options,type,'principal value 3')
+end
+end
+
+function Apply_options_tensor(md,options,type,component)
+%apply options
+if ismember('_',type) %user plotet stress_tensor
+	strings=strsplit(type,'_');
+	string=strings{1};
+else %default plot: user requested stress
+	string=type;
+end
+options=addfielddefault(options,'title',[upper(string(1)) string(2:end) ' ' component]);
+options=changefieldvalue(options,'colorbar',2);
+applyoptions(md,[],options);
+end
Index: /issm/trunk/src/m/model/plot/plot_tensor_principalaxis.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_tensor_principalaxis.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_tensor_principalaxis.m	(revision 5901)
@@ -0,0 +1,95 @@
+function plot_tensor_principalaxis(md,options,width,i,tensor,type,plot_options);
+%PLOT_TENSOR_PRINCIPALAXIS - plot ytensor principal axis
+%
+%   Usage:
+%      plot_tensor_principalaxis(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+%prepare subplot
+subplot(width,width,i); 
+
+%process data and model
+[x y z elements is2d]=processmesh(md,[],options);
+
+if ((md.dim==2)),
+	eval(['Vx=tensor.principalaxis' type(end) '(:,1); Vy=tensor.principalaxis' type(end) '(:,2);'])
+	eval(['value=tensor.principalvalue' type(end) ';']);
+	[Vx datatype]=processdata(md,Vx,options);
+	[Vy datatype]=processdata(md,Vy,options);
+	[value datatype]=processdata(md,value,options);
+else
+	eval(['Vx=tensor.principalaxis' type(end) '(:,1); Vy=tensor.principalaxis' type(end) '(:,2); Vz=tensor.principalaxis' type(end) '(:,3);'])
+	[Vx datatype]=processdata(md,Vx,options);
+	[Vy datatype]=processdata(md,Vy,options);
+	[Vz datatype]=processdata(md,Vz,options);
+	[value datatype]=processdata(md,value,options);
+end
+
+%take the center of each element if ~isongrid
+if datatype==1,
+	x=mean(md.x(md.elements'))'; y=mean(md.y(md.elements'))'; z=mean(md.z(md.elements'))';
+end
+
+%plot quivers
+if (md.dim==2),
+
+	%density
+	if exist(options,'density')
+		density=getfieldvalue(options,'density');
+		x=x(1:density:end);
+		y=y(1:density:end);
+		Vx=Vx(1:density:end);
+		Vy=Vy(1:density:end);
+		value=value(1:density:end);
+	end
+
+	%scaling:
+	delta=((min(x)-max(x))^2+(min(y)-max(y))^2)/numel(x);
+	scale=0.5/max(sqrt((Vx.^2+Vy.^2)/delta));
+	Vx=scale*Vx; Vy=scale*Vy;
+
+	pos=find(value>=0);
+	q1=quiver(x(pos),y(pos),Vx(pos),Vy(pos),'Color','r','ShowArrowHead','off','AutoScale','off');
+	hold on
+	pos=find(value<0);
+	q2=quiver(x(pos),y(pos),Vx(pos),Vy(pos),'Color','b','ShowArrowHead','off','AutoScale','off');
+
+else
+	%density
+	if exist(options,'density')
+		density=getfieldvalue(options,'density');
+		x=x(1:density:end);
+		y=y(1:density:end);
+		z=z(1:density:end);
+		Vx=Vx(1:density:end);
+		Vy=Vy(1:density:end);
+		Vz=Vz(1:density:end);
+		value=value(1:density:end);
+	end
+
+	%scaling:
+	delta=((min(x)-max(x))^2+(min(y)-max(y))^2)/numel(x);
+	scale=0.5/max(sqrt((Vx.^2+Vy.^2)/delta));
+	Vx=scale*Vx; Vy=scale*Vy; Vz=scale*Vz;
+
+	pos=find(value>=0);
+	q1=quiver3(x(pos),y(pos),z(pos),Vx(pos),Vy(pos),Vz(pos),'Color','r','ShowArrowHead','off','AutoScale','off');
+	hold on
+	pos=find(value<0);
+	q2=quiver3(x(pos),y(pos),z(pos),Vx(pos),Vy(pos),Vz(pos),'Color','b','ShowArrowHead','off','AutoScale','off');
+end
+
+%legend
+if strcmpi(type(1:6),'strain')
+	legend([q1 q2],'extension','compression')
+elseif strcmpi(type(1:6),'stress')
+	legend([q1 q2],'compression','traction')
+end
+
+%apply options
+strings=strsplit(type,'_');
+string=strings{1};
+options=addfielddefault(options,'title',[upper(string(1)) string(2:end) ' principal axis ' type(end)]);
+options=addfielddefault(options,'colorbar',0);
+applyoptions(md,[],options);
Index: /issm/trunk/src/m/model/plot/plot_thermaltransient_results.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_thermaltransient_results.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_thermaltransient_results.m	(revision 5901)
@@ -0,0 +1,24 @@
+function plot_thermaltransient_results(md,options,width,i)
+%PLOT_THERMALTRANSIENT_RESULTS - plot  results of a thermal transient solution
+%
+%   Usage:
+%      plot_thermaltransient_results(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+string='plot(md';
+for i=1:length(md.thermaltransient_results),
+	string=[string ',''data'',''thermaltransient_results(' num2str(i) ').temperature'',''view'',3,''title'',''Temperature at time ' num2str(md.thermaltransient_results(i).time) ' a'''];
+end
+string=[string ',''figure'',1,''colorbar#all'',''on'',''view'',3,''fontsize'',' num2str(options.fontsize) ',''fontweight'',' options.fontweight ');'];
+eval(string);
+clear string;
+
+string='plot(md';
+for i=2:length(md.thermaltransient_results),
+	string=[string ',''data'',md.thermaltransient_results(' num2str(i) ').temperature-md.thermaltransient_results(' num2str(i-1) ').temperature,''view'',3,''title'',''Delta temperature at time ' num2str(md.thermaltransient_results(i).time) ' a'''];
+end
+string=[string ',''figure'',2,''colorbar#all'',''on'',''fontsize'',' num2str(options.fontsize) ',''fontweight'',' options.fontweight ');'];
+eval(string);
+clear string;
+
Index: /issm/trunk/src/m/model/plot/plot_transient_field.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_transient_field.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_transient_field.m	(revision 5901)
@@ -0,0 +1,60 @@
+function plot_transient_field(md,options,width,i,data)
+%PLOT_TRANSIENT_FIELD - plot transient results
+%
+%   Usage:
+%      plot_transient_field(md,options,width,i,data);
+%
+%   See also: PLOTMODEL
+
+%Check that they are transient results
+if ~isfield(md.results,'transient'),
+	error('plot_transient_field error message: no transient results in the model');
+end
+
+%Figure out the iterations to plot and check if it is possible
+steps=getfieldvalue(options,'steps');
+maxiteration=size(md.results.transient,2);
+if max(steps)>maxiteration | min(steps)<1,
+	error(['plot_transient_field error message: problem with the steps requested, must be an interger between 0 and ' num2str(maxiteration)]);
+end
+subplotwidth=ceil(sqrt(length(steps)));
+
+%Figure out the field to plot
+if strncmpi(fliplr(data),fliplr('vx'),2),
+	field='vx';
+elseif strncmpi(fliplr(data),fliplr('vy'),2),
+	field='vy';
+elseif strncmpi(fliplr(data),fliplr('vz'),2),
+	field='vz';
+elseif strncmpi(fliplr(data),fliplr('vel'),3),
+	field='vel';
+elseif strncmpi(fliplr(data),fliplr('pressure'),8),
+	field='pressure';
+elseif strncmpi(fliplr(data),fliplr('melting'),6),
+	field='melting';
+elseif strncmpi(fliplr(data),fliplr('temperature'),11),
+	field='temperature';
+elseif strncmpi(fliplr(data),fliplr('bed'),3),
+	field='bed';
+elseif strncmpi(fliplr(data),fliplr('thickness'),9),
+	field='thickness';
+elseif strncmpi(fliplr(data),fliplr('surface'),7),
+	field='surface';
+end
+
+%process mes only once
+[x y z elements is2d]=processmesh(md,[],options);
+
+%plot data for all steps
+for i=1:length(steps),
+
+	%process data and change title if needed
+	[data datatype]=processdata(md,md.results.transient(steps(i)).(field),options);
+	options=changefieldvalue(options,'title',[field ' at time ' num2str(md.results.transient(steps(i)).time) ' a']);
+
+	%create plot of step i
+	subplot(subplotwidth,subplotwidth,i);
+	plot_unit(x,y,z,elements,data,is2d,datatype,options)
+	applyoptions(md,data,options);
+
+end
Index: /issm/trunk/src/m/model/plot/plot_transient_movie.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_transient_movie.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_transient_movie.m	(revision 5901)
@@ -0,0 +1,60 @@
+function plot_transient_movie(md,options,width,i);
+%PLOT_TRANSIENT_MOVIE - plot a transient result as a movie
+%   Usage:
+%      plot_transient_movie(md,options,width,i);
+%
+%   See also: PLOTMODEL, PLOT_UNIT, PLOT_MANAGER
+
+	%prepare subplot
+	subplot(width,width,i); 
+
+	%xlim
+	if exist(options,'transient_movie_field'),
+		field=getfieldvalue(options,'transient_movie_field');
+	else
+		error('specify transient_movie_field in options list');
+	end
+
+	%process model
+	[x y z elements is2d]=processmesh(md,[],options);
+
+	%loop over the time steps
+	for i=1:length(md.results.transient)
+		eval(['data=md.results.transient(' num2str(i) ').' num2str(field) ';']);
+
+		%process data
+		[data datatype]=processdata(md,data,options);
+		titlestring=[field ' at time ' num2str(md.results.transient(i).time) ' year'];
+		plot_unit(x,y,z,elements,data,is2d,datatype,options)
+		apply_options_movie(md,options,titlestring);
+		
+		if exist(options,'transient_movie_output'),
+			set(gcf,'Renderer','zbuffer','color','white'); %fixes a bug on Mac OS X (not needed in future Matlab version)
+			if i==1,
+				%initialize images and frame
+				frame=getframe(gcf);
+				[images,map]=rgb2ind(frame.cdata,256,'nodither');
+				images(1,1,1,length(md.results.transient))=0;
+			else
+				frame=getframe(gcf);
+				images(:,:,1,i) = rgb2ind(frame.cdata,map,'nodither');
+			end
+		else
+			pause(0.1)
+		end
+	end
+
+	%output movie if requested.
+	if exist(options,'transient_movie_output'),
+		filename=getfieldvalue(options,'transient_movie_output');
+		imwrite(images,map,filename,'DelayTime',getfieldvalue(options,'transient_movie_time',2),'LoopCount',inf)
+	end
+
+end %function
+
+function apply_options_movie(md,options,titlestring)
+	%apply options
+	options=addfielddefault(options,'title',titlestring);
+	options=addfielddefault(options,'colorbar',1);
+	applyoptions(md,[],options);
+end
Index: /issm/trunk/src/m/model/plot/plot_transient_results.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_transient_results.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_transient_results.m	(revision 5901)
@@ -0,0 +1,77 @@
+function plot_transient_results(md,options,width,i)
+%PLOT_TRANSIENT_RESULTS - plot transient results
+%
+%   Usage:
+%      plot_transient_results(md,options,width,i);
+%
+%   See also: PLOTMODEL
+
+fontsize=getfieldvalue(options,'fontsize',14);
+fontweight=getfieldvalue(options,'fontweight','n');
+
+%Prepare window distribution
+%Get screen geometry
+mp = get(0, 'MonitorPositions');
+%Build window sizes
+if size(mp,1)>=2        %several monitors, use the second one
+	bdwidth=mp(2,1)+5; topbdwidth=mp(2,2)+20; W=mp(2,3)/3; H=mp(2,4)/2;
+else                    %only one monitor
+	bdwidth=5;         topbdwidth=20;         W=mp(1,3)/3; H=mp(1,4)/2;
+end
+pos1=[bdwidth  H+bdwidth  W-2*bdwidth  H-bdwidth-topbdwidth];
+pos2=pos1+[W 0 0 0]; pos3=pos1+[2*W 0 0 0]; pos4=pos1+[0 -H 0 0]; pos5=pos1+[W -H 0 0]; pos6=pos1+[2*W -H 0 0];
+%Create windows
+figure(1);close;
+figure('Position',pos1); figure('Position',pos2);figure('Position',pos3);figure('Position',pos4);figure('Position',pos5);figure('Position',pos6);
+
+string='plotmodel(md';
+for i=1:length(md.results.transient),
+	string=[string ',''data'',md.results.transient(' num2str(i) ').thickness,''title'',''Thickness at time ' num2str(md.results.transient(i).time) ' a'''];
+end
+string=[string ',''figure'',1,''colorbar#all'',''on'',''fontsize'',' num2str(fontsize) ',''fontweight'',''' fontweight ''');'];
+eval(string);
+clear string;
+
+string='plotmodel(md';
+for i=1:length(md.results.transient),
+	string=[string ',''data'',md.results.transient(' num2str(i) ').vel,''view'',3,''title'',''Velocity at time ' num2str(md.results.transient(i).time) ' a'''];
+end
+string=[string ',''figure'',2,''colorbar#all'',''on'',''fontsize'',' num2str(fontsize) ',''fontweight'',''' fontweight  ''');'];
+eval(string);
+clear string;
+
+if md.dim==3,
+	string='plotmodel(md';
+	for i=1:length(md.results.transient),
+		string=[string ',''data'',md.results.transient(' num2str(i) ').temperature,''view'',3,''title'',''Temperature at time ' num2str(md.results.transient(i).time) ' a'''];
+	end
+	string=[string ',''figure'',3,''colorbar#all'',''on'',''view'',3,''fontsize'',' num2str(fontsize) ',''fontweight'',''' fontweight  ''');'];
+	eval(string);
+	clear string;
+end
+
+string='plotmodel(md';
+for i=2:length(md.results.transient),
+	string=[string ',''data'',md.results.transient(' num2str(i) ').thickness-md.results.transient(' num2str(i-1) ').thickness,''title'',''Delta thickness at time ' num2str(md.results.transient(i).time) ' a'''];
+end
+string=[string ',''figure'',4,''colorbar#all'',''on'',''fontsize'',' num2str(fontsize) ',''fontweight'',''' fontweight  ''');'];
+eval(string);
+clear string;
+
+string='plotmodel(md';
+for i=2:length(md.results.transient),
+	string=[string ',''data'',md.results.transient(' num2str(i) ').vel-md.results.transient(' num2str(i-1) ').vel,''view'',3,''title'',''Delta velocity at time ' num2str(md.results.transient(i).time) ' a'''];
+end
+string=[string ',''figure'',5,''colorbar#all'',''on'',''fontsize'',' num2str(fontsize) ',''fontweight'',''' fontweight  ''');'];
+eval(string);
+clear string;
+
+if md.dim==3,
+	string='plotmodel(md';
+	for i=2:length(md.results.transient),
+		string=[string ',''data'',md.results.transient(' num2str(i) ').temperature-md.results.transient(' num2str(i-1) ').temperature,''view'',3,''title'',''Delta temperature at time ' num2str(md.results.transient(i).time) ' a'''];
+	end
+	string=[string ',''figure'',6,''colorbar#all'',''on'',''fontsize'',' num2str(fontsize) ',''fontweight'',''' fontweight  ''');'];
+	eval(string);
+	clear string;
+end
Index: /issm/trunk/src/m/model/plot/plot_unit.m
===================================================================
--- /issm/trunk/src/m/model/plot/plot_unit.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plot_unit.m	(revision 5901)
@@ -0,0 +1,76 @@
+function plot_unit(x,y,z,elements,data,is2d,datatype,options)
+%PLOT_UNIT - unit plot, display data
+%
+%   Usage:
+%      plot_unit(x,y,z,elements,data,is2d,datatype,options);
+%
+%   See also: PLOTMODEL, PLOT_MANAGER
+
+%edgecolor
+edgecolor=getfieldvalue(options,'edgecolor','none');
+%P=get(gca,'pos');
+%P(3)=P(3)+0.04;
+%P(1)=P(1)-0.02;
+%set(gca,'pos',P);
+
+switch datatype,
+
+	%element plot
+	case 1,
+
+		pos=find(~isnan(data)); %needed fpr element on water
+		if is2d,
+			A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); 
+			patch( 'Faces', [A B C], 'Vertices', [x y z],'CData', data(pos),'FaceColor','flat','EdgeColor',edgecolor);
+		else
+			A=elements(pos,1); B=elements(pos,2); C=elements(pos,3); D=elements(pos,4); E=elements(pos,5); F=elements(pos,6);
+			patch( 'Faces', [A B C],  'Vertices', [x y z],'CData', data(pos),'FaceColor','flat','EdgeColor',edgecolor);
+			patch( 'Faces', [D E F],  'Vertices', [x y z],'CData', data(pos),'FaceColor','flat','EdgeColor',edgecolor);
+			patch( 'Faces', [A B E D],'Vertices', [x y z],'CData', data(pos),'FaceColor','flat','EdgeColor',edgecolor);
+			patch( 'Faces', [B E F C],'Vertices', [x y z],'CData', data(pos),'FaceColor','flat','EdgeColor',edgecolor);
+			patch( 'Faces', [C A D F],'Vertices', [x y z],'CData', data(pos),'FaceColor','flat','EdgeColor',edgecolor);
+		end
+
+	%node plot
+	case 2,
+
+		if is2d,
+			A=elements(:,1); B=elements(:,2); C=elements(:,3); 
+			patch( 'Faces', [A B C], 'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
+		else
+			A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+			patch( 'Faces', [A B C],  'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [D E F],  'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [A B E D],'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [B E F C],'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [C A D F],'Vertices', [x y z],'FaceVertexCData', data(:),'FaceColor','interp','EdgeColor',edgecolor);
+		end
+
+	%quiver plot
+	case 3,
+
+		if is2d,
+			plot_quiver(x,y,data(:,1),data(:,2),options);
+		else
+			plot_quiver3(x,y,z,data(:,1),data(:,2),data(:,3),options);
+		end
+
+	%Patch plot
+	case 4,
+
+		if is2d,
+			patch( 'Faces',elements,'Vertices',[x y],'CData',data,'FaceColor','interp','EdgeColor',edgecolor);
+		else
+			A=elements(:,1); B=elements(:,2); C=elements(:,3); D=elements(:,4); E=elements(:,5); F=elements(:,6);
+			patch( 'Faces', [A B C], 'Vertices', [x y z],'CData', data,'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [D E F], 'Vertices', [x y z],'CData', data,'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [A B E D], 'Vertices', [x y z],'CData', data,'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [B E F C ], 'Vertices', [x y z],'CData', data,'FaceColor','interp','EdgeColor',edgecolor);
+			patch( 'Faces', [C A D F ], 'Vertices', [x y z],'CData', data,'FaceColor','interp','EdgeColor',edgecolor);
+		end
+
+	otherwise,
+		error(['case ' num2str(datatype) ' not supported']);
+
+	end
+end
Index: /issm/trunk/src/m/model/plot/plotanalyse.m
===================================================================
--- /issm/trunk/src/m/model/plot/plotanalyse.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plotanalyse.m	(revision 5901)
@@ -0,0 +1,23 @@
+function plotanalyse(md)
+%PLOTANALYSE - analyse entire model by plotting everything!
+%
+%   Usage:
+%      plotanalyse(md)
+
+%Do a series of plots that will help the user analyse what is going on. 
+plot(md,'data','segmentonneumann_diag','title','dynamic boundary conditions',...
+		'data','gridondirichlet_diag','title','fixed velocity grids',...
+		'data','vx_obs','title','vx observation (m/s)',...
+		'data','vy_obs','title','vy observation (m/s)',... 
+		'colorbar#all','on','figure',1);
+
+plot(md,'data','surface','title','surface','data','thickness','title','thickness',...
+        'data','bed','title','bedrock','colorbar#all','on','figure',2);
+
+plot(md,'data','drag','title','drag coefficient','data','p','title','p coeff',...
+         'data','q','title','q coeff','colorbar#all','on','figure',3);
+
+plot(md,'data','elementoniceshelf','title','elements on iceshelf',...
+        'data','gridoniceshelf','title','nodes on iceshelf',...
+		'data','elementonicesheet','title','elements on icesheet',...
+		'data','gridonicesheet','title','nodes on icesheet','colorbar#all','on','figure',4);
Index: /issm/trunk/src/m/model/plot/plotdoc.m
===================================================================
--- /issm/trunk/src/m/model/plot/plotdoc.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plotdoc.m	(revision 5901)
@@ -0,0 +1,144 @@
+function plotdoc()
+%PLOTDOC - plot documentation
+%
+%   Usage:
+%      plotdoc()
+
+disp(' ');
+disp('   Plot usage: plotm(model,varargin)');
+disp('   Options: ');
+disp('       ''figure'': figure number');
+disp('       ''data'' : what we want to plot');
+disp('                Available values for ''data'' are: ');
+disp('                  - any field of the model structure. ex: plot(md,''data'',''vel''), or plot(md,''data'',md.vel)');
+disp('                  - ''basal_drag'': plot the basal drag on the bed (in kPa)');
+disp('                  - ''basal_dragx'' or ''basal_dragy'' : plot a component of the basal drag on the bed (in kPa)');
+disp('                  - ''boundaries'': this will draw all the segment boundaries to the model, including rifts.');
+disp('                  - ''BC'': this will draw all the boundary conditions (Dirichlet and Neumann).');
+disp('                  - ''deviatoricstress_tensor'': plot the components of the deviatoric stress tensor (tauxx,tauyy,tauzz,tauxy,tauxz,tauyz) if computed');
+disp('                  - ''deviatoricstress_principal'': plot the deviatoricstress tensor principal axis and principal values');
+disp('                  - ''deviatoricstress_principalaxis1'': arrow plot the first principal axis of the deviatoricstress tensor(replace 1 by 2 or 3 if needed)');
+disp('                  - ''driving_stress'': plot the driving stress (in kPa)');
+disp('                  - ''elements_type'': model used for each element');
+disp('                  - ''elementnumbering'': numbering of elements');
+disp('                  - ''gridnumbering'': numbering of grids');
+disp('                  - ''highlightelements'': to highlight elements to highlight the element list');
+disp('                  - ''highlightgrids'': to highlight grids (use highlight option to enter the grid list');
+disp('                  - ''mesh'': draw mesh using trisurf');
+disp('                  - ''riftvel'': velocities along rifts');
+disp('                  - ''riftrelvel'': relative velocities along rifts');
+disp('                  - ''riftpenetration'': penetration levels for a fault');
+disp('                  - ''riftfraction'': fill fractions for every node of the rifts');
+disp('                  - ''rifts'': plot mesh with an offset so that rifts are visible');
+disp('                  - ''strainrate_tensor'': plot the components of the strainrate tensor (exx,eyy,ezz,exy,exz,eyz) if computed');
+disp('                  - ''strainrate_principal'': plot the strainrate tensor principal axis and principal values)');
+disp('                  - ''strainrate_principalaxis1'': arrow plot the first principal axis of the strainrate tensor(replace 1 by 2 or 3 if needed)');
+disp('                  - ''stress_tensor'': plot the components of stress tensor (sxx,syy,szz,sxy,sxz,syz) if computed');
+disp('                  - ''stress_principal'': plot the stress tensor principal axis and principal values');
+disp('                  - ''stress_principalaxis1'': arrow plot the first principal axis of the stress tensor(replace 1 by 2 or 3 if needed)');
+disp('                  - ''transient_results'': this will display all the time steps of a transient run (use steps to specify the steps requested)');
+disp('                  - ''transient_vel'': this will display the velocity for the time steps requested in ''steps'' of a transient run');
+disp('                  - ''transient_vel'': vel can be by any field of the transient results (vx, vy, vz, vel, temperature, melting, pressure, bed, thickness, surface)');
+disp('                  - ''transient_movie'': this will display the time steps of a given field of a transient run');
+disp('                  - ''transient_movie_field'': field to be displayed when doing  transient_movie data display');
+disp('                  - ''transient_movie_output'': filename if output is desired for movie');
+disp('                  - ''transient_movie_time'': time for each image (default 2 seconds)');
+disp('                  - ''thermaltransient_results'': this will display all the time steps of a thermal transient run');
+disp('                  - ''qmuhistnorm'': histogram normal distribution. needs option qmudata');
+disp('                  - ''qmumean'': plot of mean distribution in sampling analysis with scaled response. needs option qmudata for descriptor');
+disp('                  - ''qmustddev'': plot of stddev distribution in sampling analysis with scaled response. needs option qmudata for descriptor');
+disp('                  - ''part_hist'': partitioning node and area histogram');
+
+disp('       ''alloptions'': apply the options to all subplots if ''on''');
+disp('       ''axis'': same as standard matlab option (''equal'',''off'',''equal on'',...)');
+disp('       ''basin'': zoom on a given basin (''pineislandglacier'',''ronneiceshelf'', type basinzoom for a complete list)');
+disp('       ''caxis'': modify  colorbar range. (array of type [a b] where b>=a)');
+disp('       ''colorlevels'':  N or {value1,valu2,value3,...} used if quiver, use different colors for the given number of colors or limits');
+disp('       ''colorbar'': add colorbar (string ''on'' or ''off'')');
+disp('       ''colorbartitle'': colorbar title (string)');
+disp('       ''colorbarpos'': [x,y,dx,dy] where x,y,dx and dy are within [0 1]');
+disp('       ''colorbarcornerposition'': ''West'',''North'',etc ...');
+disp('       ''colorbartitlerotation'': -90, etc ...');
+disp('       ''colorbarfontsize'': specify colorbar fontsize');
+disp('       ''colormap'': same as standard matlab option (''jet'',''HSV'',''cool'',''spring'',''gray'',...)');
+disp('       ''contourlevels'': N or {value1,valu2,value3,...} add the contours of the specified values or N contours');
+disp('       ''contourticks'': ''on'' or ''off'' to display the ticks of the contours');
+disp('       ''contouronly'': ''on'' or ''off'' to display the contours on a white background');
+disp('       ''contourcolor'': ticks and contour color');
+disp('       ''density'': density of quivers (one arrow every N nodes, N integer)');
+disp('       ''inset'': add an inset (zoom) of the current figure if 1 (use ''insetx'', ''insety'' and ''insetpos'' to determine the inset position and content)');
+disp('       ''insetx'': [min(x) max(x)] where min(x) and max(x) are values determining the inset content');
+disp('       ''insety'': [min(y) max(y)] where min(y) and max(y) are values determining the inset content');
+disp('       ''insetpos'': [x,y,dx,dy] where x,y,dx and dy are within [0 1]');
+disp('       ''streamlines'': N (number of stream lines) or {[x1 y1],...} (coordinates of seed points) add streanlines on current figure');
+disp('       ''edgecolor'': same as standard matlab option EdgeColor (color name: ''black'' or RGB array: [0.5 0.2 0.8])');
+disp('       ''fontsize'': same as standard matlab option (normal: ''n'',bold: ''b'',light: ''l'',demi: ''d'')');
+disp('       ''fontweight'': same as standard matlab option (10,14,...)');
+disp('       ''fontcolor'': same as standard matlab option');
+disp('       ''highlight'': highlights certain grids or elements when using ''gridnumbering'' or ''elementnumbering'' or ''highlightgrids '' or ''highlightelements'' option');
+disp('       ''resolution'': resolution used by section value (array of type [horizontal_resolution vertical_resolution])');
+disp('                       horizontal_resolution must be in meter, and vertical_resolution a number of layers');
+disp('       ''showsection'': show section used by ''sectionvalue'' (string ''on'' or a number of labels)');
+disp('       ''sectionvalue'': give the value of data on a profile given by an Argus file (string ''Argusfile_name.exp'')');
+disp('       ''smooth'': smooth element data (string ''yes'' or integer)');
+disp('       ''title'': same as standard matlab option');
+disp('       ''view'': same as standard matlab option (ex: 2, 3 or [90 180]');
+disp('       ''xlim'': same as standard matlab option (ex: [0 500])');
+disp('       ''ylim'': same as standard matlab option');
+disp('       ''zlim'': same as standard matlab option');
+disp('       ''xlabel'': same as standard matlab option (ex:''km'')');
+disp('       ''ylabel'': same as standard matlab option');
+disp('       ''xticklabel'': specifiy xticklabel');
+disp('       ''yticklabel'': specifiy yticklabel');
+disp('       ''overlay'': yes or no. This will overlay a radar amplitude image behind');
+disp('       ''cutoff'': all values below cutoff will be taken as cutoff (default is 1.5)');
+disp('       ''highres'': resolution of overlayed radar amplitude image (default is 0, high resolution is 1).');
+disp('       ''hem'': specify hemisphere ''n'' or ''s'' (default is ''s'').');
+disp('       ''alpha'': transparency coefficient (the higher, the more transparent). Default is 1.5');
+disp('       ''scaling'': scaling factor used by quiver plots. Default is 0.4');
+disp('       ''autoscale'': set to ''off'' to have all the quivers with the same size. Default is ''on''');
+disp('       ''expdisp'': plot exp file on top of a data plot. provide exp file as an argument (use a cell of strings if more than one)');
+disp('       ''expstyle'': marker style for expdisp plot (use a cell of strings if more than one)');
+disp('       ''linewidth'': line width for expdisp plot');
+disp('       ''border'': size of display border (in pixels). active only for overlay plots');
+disp('       ''text'': print string, use a cell of strings if more than one');
+disp('       ''textposition'': [x y] position of text, use a cell of strings if more than one');
+disp('       ''textsize'':  same as standard ''FontSize'' matlab option applied to text, use a cell of strings if more than one');
+disp('       ''textweight'':  same as standard ''FontWeight'' matlab option applied to text, use a cell of strings if more than one');
+disp('       ''textcolor'':  same as standard ''color'' matlab option applied to text, use a cell of strings if more than one');
+disp('       ''iceshelf'': ''none'' if ice shelves are to not be plotted');
+disp('       ''icesheet'': ''none'' if ice sheets are to not be plotted');
+disp('       ''partitionedges'': ''off'' by default. overlay plot of partition edges');
+disp('       ''log'': value of log');
+disp('       ''latlon'': ''on'' or {latstep lonstep [resolution [color]]} where latstep,longstep and resolution are in degrees, color is a [r g b] array');
+disp('       ''latlonnumbering'': ''on'' or {latgap longap colornumber latangle lonangle} where latgap and longap are pixel gaps for the numbers,'); 
+disp('       ''latlonclick'': ''on'' to click on latlon ticks positions');
+disp('                   colornumber is a [r g b] array and latangle and lonangle are angles to flip the numbers');
+disp('       ''northarrow'': add an arrow pointing north, ''on'' for default value or [x0 y0 length [ratio [width]]] where (x0,y0) are the coordinates of the base, and ratio=headlength/length');
+disp('       ''offset'': mesh offset used by ''rifts'', default is 500');
+disp('       ''scaleruler'': add a scale ruler, ''on'' for default value or [x0 y0 length width numberofticks] where (x0,y0) are the coordinates of the lower left corner');
+disp('       ''showregion'': show domain in Antarctica on an inset, use ''insetpos'' properties');
+disp('       ''visible'': ''off'' to make figure unvisible, default is ''on''');
+disp('       ''wrapping'': repeat ''n'' times the colormap (''n'' must be an integer)');
+disp('       ''unit'': by default, in m, otherwise, ''km'' is available');
+disp('       ''qmudata'': data for qmu  plots.');
+disp('                  {dresp1   ,dresp2  ,hmin,hmax,hnint} or {samp,desc,mu,sigma,hmin,hmax,hnint}');
+disp('                  where dresp1 is a structure array of responses (where we need samp and desc), ');
+disp('                  dresp2 is a structure array of responses (where we only need mu and sigma)');
+disp('                  hmin,hmax and hnint are the minimum, maximum and number of intervals of the histogram (optional)');
+disp('       ''position'': position of figure. specify name of person for which position settings are hardcoded in applyoptions.m');
+disp('       ''hmin'': (numeric, minimum for histogram)');
+disp('       ''hmax'': (numeric, maximum for histogram)');
+disp('       ''hnint'': (numeric, number of intervals for histogram)');
+disp('       ''ymin1'': (numeric, minimum of histogram y-axis)');
+disp('       ''ymax1'': (numeric, maximum of histogram y-axis)');
+disp('       ''ymin2'': (numeric, minimum of cdf y-axis)');
+disp('       ''ymax2'': (numeric, maximum of cdf y-axis)');
+disp('       ''cdfplt'': (char, ''off'' to turn off cdf line plots)');
+disp('       ''cdfleg'': (char, ''off'' to turn off cdf legends)');
+disp('       ''segmentnumbering'': (''off'' by default)');
+disp('       any options (except ''data'') can be followed by ''#i'' where ''i'' is the subplot number, or ''#all'' if applied to all plots');
+disp('  ');
+disp('   Examples:');
+disp('       plotmodel(md,''data'',''vel'',''data'',''mesh'',''view#2'',3,''colorbar#all'',''on'',''axis#1'',''off equal'')');
+disp('       plotmodel(md,''data'',''highlightelements'',''highlight'',[1 4 10],''expdisp'',{''domain1.exp'' ''domain2.exp'' ''domain3.exp''})');
Index: /issm/trunk/src/m/model/plot/plotmodel.m
===================================================================
--- /issm/trunk/src/m/model/plot/plotmodel.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/plotmodel.m	(revision 5901)
@@ -0,0 +1,60 @@
+function plotmodel(md,varargin)
+%At command prompt, type plotdoc for help on documentation.
+
+global ISSM_DIR
+if isempty(ISSM_DIR),
+	error('ISSM_DIR variable got erased! This variable is needed to run Ice code correctly. Please rerun your startup file.');
+end
+
+%First process options
+options=plotoptions(varargin{:});
+
+%get number of subplots
+subplotwidth=ceil(sqrt(options.numberofplots));
+
+%if nlines and ncols specified, then bypass.
+if exist(options.list{1},'nlines'),
+	nlines=getfieldvalue(options.list{1},'nlines');
+else 
+	nlines=subplotwidth;
+end
+
+if exist(options.list{1},'ncols'),
+	ncols=getfieldvalue(options.list{1},'ncols');
+else 
+	ncols=subplotwidth;
+end
+
+%check that nlines and ncols were given at the same time!
+if ((exist(options.list{1},'ncols') & ~exist(options.list{1},'ncols')) | (~exist(options.list{1},'ncols') & exist(options.list{1},'ncols')))
+	error('plotmodel error message: nlines and ncols  need to be specified together, or not at all');
+end
+
+%Get figure number and number of plots
+figurenumber=options.figurenumber;
+numberofplots=options.numberofplots;
+
+%go through subplots
+if numberofplots,
+		
+	%Create figure 
+	if strcmpi(getfieldvalue(options.list{1},'visible','on'),'off'),
+		F=figure(figurenumber);clf;
+		set(F,'Visible','Off');
+	else
+		figure(figurenumber),clf;
+	end
+
+	%Use zbuffer renderer (snoother colors)
+	set(gcf,'Renderer','zbuffer');
+
+	%Go through all data plottable
+	for i=1:numberofplots,
+
+		%call unit plot
+		plot_manager(md,options.list{i},subplotwidth,nlines,ncols,i);
+
+	end
+else
+	error('plotmodel error message: no output data found. ');
+end
Index: /issm/trunk/src/m/model/plot/processdata.m
===================================================================
--- /issm/trunk/src/m/model/plot/processdata.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/processdata.m	(revision 5901)
@@ -0,0 +1,169 @@
+function [data datatype]=processdata(md,data,options);
+%PROCESSDATA - process data to be plotted
+%
+%   datatype = 1 -> elements
+%   datatype = 2 -> nodes
+%   datatype = 3 -> node quivers
+%   datatype = 4 -> patch
+%
+%   Usage:
+%      [data datatype]=processdata(md,data,options);
+%
+%   See also: PLOTMODEL, PROCESSMESH
+
+%check format
+if (iscell(data) | isempty(data) | length(data)==0 | (length(data)==1 & ~isstruct(data) & isnan(data))),
+	error('plotmodel error message: data provided is empty');
+end
+
+%Process Patch
+if isstruct(data) 
+	if (isfield(data,'index') & isfield(data,'value')),
+		data=data.value;
+		data=data';
+		data=data(:);
+		datatype=4;
+	else
+		error('structure other than Patch not supported yet');
+	end
+else
+	%initialize datatype
+	datatype=0;
+end
+
+%get datatype
+datasize=size(data);
+
+%non patch processing
+if datatype~=4,
+
+	%transpose data if necessary
+	if (size(data,2) > size(data,1)),
+		data=data';
+	end
+	datasize=size(data);
+
+	%convert to double if necessary
+	if ~isnumeric(data);
+		disp('processdata info message: data is not numeric (logical?). Converted to double');
+		data=double(data);
+	end
+
+	%check length
+	if datasize(1)~=md.numberofgrids & datasize(1)~=md.numberofelements & datasize(1)~=md.numberofgrids*6 & (md.dim==3 & ~(datasize(1)==md.numberofelements2d | datasize(1)==md.numberofgrids2d))
+		error('plotmodel error message: data not supported yet');
+	end
+
+	%quiver?
+	if datasize(2)>1,
+		datatype=3;
+
+		%check number of columns, add zeros if necessary,
+		if (md.dim==3)
+			if datasize(2)==2,
+				data=[data, zeros(datasize(1),1)];
+			elseif datasize(2)~=3,
+				error('plotmodel error message: data provided should have 2 or 3 columns for quiver plot, and 1 for regular plot');
+			end
+		%elseif ((md.dim==2) & datasize(2)~=2),
+		%	error('plotmodel error message: data provided should have 2 columns for quiver plot, and 1 for regular plot');
+		end
+	end
+
+	%treat the case datasize(1)=6*grids
+	if datasize(1)==6*md.numberofgrids
+		%keep the only norm of data
+		data1=data(1:6:md.numberofgrids*6,:);
+		data2=data(2:6:md.numberofgrids*6,:);
+		data=sqrt(data1.^2+data2.^2);
+		datasize(1)=md.numberofgrids;
+		%---> go to grid data
+	end
+
+	%treat the case datasize(1)=grids2d
+	if (md.dim==3 & datasize(1)==md.numberofgrids2d),
+		data=project3d(md,data,'node');
+		datasize(1)=md.numberofgrids;
+		%---> go to grid data
+	end
+
+	%treat the case datasize(1)=grids2d
+	if (md.dim==3 & datasize(1)==md.numberofelements2d),
+		data=project3d(md,data,'element');
+		datasize(1)=md.numberofelements;
+		%---> go to grid data
+	end
+
+	%smoothing?
+	if exist(options,'smooth')
+		data=averaging(md,data,getfieldvalue(options,'smooth'));
+		datasize(1)=md.numberofgrids;
+		%---> go to grid data
+	end
+end
+
+%element data
+if (datasize(1)==md.numberofelements & datasize(2)==1),
+
+	%Initialize datatype if non patch
+	if datatype~=4,
+		datatype=1;
+	end
+
+	%ice sheet only?
+	if getfieldvalue(options,'iceshelf',1)==0,
+		data(find(md.elementoniceshelf),:)=NaN;
+	end
+	%ice shelf only?
+	if getfieldvalue(options,'icesheet',1)==0,
+		data(find(~md.elementoniceshelf),:)=NaN;
+	end
+	%no water?
+	if getfieldvalue(options,'water',1)==0,
+		data(find(md.elementonwater),:)=NaN;
+	end
+	%log?
+	if exist(options,'log'),
+		pos=find(~isnan(data));
+		data(pos)=log(data(pos))/log(getfieldvalue(options,'log'));
+	end
+end
+
+%grid data
+if (datasize(1)==md.numberofgrids & datasize(2)==1),
+	datatype=2;
+	%ice sheet only?
+	if getfieldvalue(options,'iceshelf',1)==0,
+		pos=find(md.gridoniceshelf);
+		data(pos,:)=NaN;
+	end
+	%ice shelf only?
+	if getfieldvalue(options,'icesheet',1)==0,
+		pos=find(md.gridonicesheet);
+		data(pos,:)=NaN;
+	end
+	%no water?
+	if getfieldvalue(options,'water',1)==0,
+		pos=find(md.gridonwater);
+		data(pos,:)=NaN;
+	end
+	%log?
+	if exist(options,'log'),
+		data=log(data)/log(getfieldvalue(options,'log'));
+	end
+
+end
+
+%layer projection? 
+if getfieldvalue(options,'layer',0)>=1,
+	data=project2d(md,data,getfieldvalue(options,'layer')); %project onto 2d mesh
+end
+
+%control arrow density if quiverplot
+if datatype==3 & exist(options,'density')
+	databak=data;
+	data=NaN*ones(datasize);
+	density=getfieldvalue(options,'density');
+	data(1:density:end,:)=databak(1:density:end,:);
+	clear databak
+end
Index: /issm/trunk/src/m/model/plot/processmesh.m
===================================================================
--- /issm/trunk/src/m/model/plot/processmesh.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/processmesh.m	(revision 5901)
@@ -0,0 +1,71 @@
+function [x y z elements is2d]=processmesh(md,data,options);
+%PROCESSMESH - process mesh to be plotted
+%
+%   Usage:
+%      [x y z elements is2d]=processmesh(md,data,options)
+%
+%   See also: PLOTMODEL, PROCESSDATA
+
+%some checks
+if md.numberofgrids==md.numberofelements
+	error('plot error message: the number of elements is the same as the number of grids! cannot plot anything with model/plot, use matlab/plot instead')
+end
+
+if (isempty(data) | ~isstruct(data)),
+	%first load x,y, etc ... to speed up plot
+	x=md.x;
+	x2d=md.x2d;
+	y=md.y;
+	y2d=md.y2d;
+	z=md.z;
+	z2d=md.z2d;
+	elements2d=md.elements2d;
+	elements=md.elements;
+	elements_type2d=md.elements_type2d;
+
+	%is it a 2d plot?
+	if (md.dim==2);
+		is2d=1;
+	elseif (md.dim==3),
+		if getfieldvalue(options,'layer',0)>=1,
+			is2d=1;
+		else
+			is2d=0;
+		end
+	else
+		error(['dim = ' num2str(md.dim) ' not supported yet']);
+	end
+
+	%layer projection? 
+	if getfieldvalue(options,'layer',0)>=1,
+		%we modify the mesh temporarily to a 2d mesh from which the 3d mesh was extruded. 
+		x=x2d;
+		y=y2d;
+		z=z2d;
+		elements=elements2d;
+		elements_type=elements_type2d;
+	end
+else
+	%Process Patch
+	if (md.dim==2),
+		elements=transpose(reshape(1:3*md.numberofelements,3,md.numberofelements));
+		x=transpose(reshape(md.x(data.index)',1,3*md.numberofelements));
+		y=transpose(reshape(md.y(data.index)',1,3*md.numberofelements));
+		z=zeros(3*md.numberofelements,1);
+		is2d=1;
+	else
+		elements=transpose(reshape(1:6*md.numberofelements,6,md.numberofelements));
+		x=transpose(reshape(md.x(data.index)',1,6*md.numberofelements));
+		y=transpose(reshape(md.y(data.index)',1,6*md.numberofelements));
+		z=transpose(reshape(md.z(data.index)',1,6*md.numberofelements));
+		is2d=0;
+	end
+end
+
+%units
+if exist(options,'unit'),
+	unit=getfieldvalue(options,'unit');
+	x=x*unit;
+	y=y*unit;
+	z=z*unit;
+end
Index: /issm/trunk/src/m/model/plot/quiver_colorbar.m
===================================================================
--- /issm/trunk/src/m/model/plot/quiver_colorbar.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/quiver_colorbar.m	(revision 5901)
@@ -0,0 +1,41 @@
+function quiver_colorbar(quivers,options)
+%QUIVER_COLORBAR - colorbar for quiver plots
+%
+%   Usage:
+%      quiver_colorbar(quivers,options)
+
+if  strcmpi(getfieldvalue(options,'colorbar','on'),'on'),
+
+	%build ticks
+	hcb=colorbar('peer',gca,'location','EastOutside');
+	ticklabel=cell(1,length(quivers.levels));
+	for i=1:length(quivers.levels),
+		ticklabel{i}=num2str(round_ice(quivers.levels(i),3));
+	end
+	tickpos=1:quivers.numcolors+1;
+
+	%remove ticks if to many have been created
+	proportion=round(length(quivers.levels)/10);
+	if proportion>1,
+		ticklabel=ticklabel(1:proportion:end);
+		tickpos=tickpos(1:proportion:end);
+	end
+
+	%draw colorbar
+	set(hcb,'YTickLabel',ticklabel,'YTick',tickpos);
+	%position
+	if exist(options,'colorbarpos'),
+		set(hcb,'Position',getfieldvalue(options,'colorbarpos'));
+	end
+	%fontsize
+	fontsize=getfieldvalue(options,'fontsize',14);
+	set(hcb,'FontSize',fontsize);
+	
+	if exist(options,'colorbartitle'),
+		backup=gca;
+		axes(hcb);lab=ylabel(getfieldvalue(options,'colorbartitle'));
+		set(lab,'Rotation',getfieldvalue(options,'colorbartitlerotation',-90));
+		set(lab,'VerticalAlignment','bottom');
+		axes(backup);
+	end
+end
Index: /issm/trunk/src/m/model/plot/quiver_process.m
===================================================================
--- /issm/trunk/src/m/model/plot/quiver_process.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/quiver_process.m	(revision 5901)
@@ -0,0 +1,70 @@
+function [quivers,palette]=quiver_process(x,y,u,v,options)
+%QUIVER_PROCESS - process data for color quiver plot
+%
+%   Usage:
+%      [quivers,palette]=quiver_process(x,y,u,v,options)
+
+%keep only non NaN elements
+pos=find(~isnan(x) & ~isnan(y) & ~isnan(u) & ~isnan(v));
+x=x(pos); y=y(pos);
+u=u(pos); v=v(pos);
+
+%get Norm Min and Max
+Norm=sqrt(u.^2+v.^2);
+Min=min(Norm);
+Max=max(Norm);
+
+%Scale data
+scalingfactor=getfieldvalue(options,'scaling',0.40);
+if strcmpi(getfieldvalue(options,'autoscale','on'),'off'),
+	delta=((min(x)-max(x))^2+(min(y)-max(y))^2)/numel(x);
+	u=scalingfactor*sqrt(delta)*u./Norm;
+	v=scalingfactor*sqrt(delta)*v./Norm;
+else
+	delta=((min(x)-max(x))^2+(min(y)-max(y))^2)/numel(x);
+	u=scalingfactor*sqrt(delta)*u./max(Norm);
+	v=scalingfactor*sqrt(delta)*v./max(Norm);
+end
+
+%number of colors?
+colorlevels=getfieldvalue(options,'colorlevels',30);
+if isnumeric(colorlevels),
+	if isnan(colorlevels),
+		numcolors=30;
+	else
+		numcolors=colorlevels;
+	end
+	levels=round_ice(linspace(Min,Max,numcolors+1),2);
+else
+	levels=zeros(1,length(colorlevels)+2);
+	levels(1)=Min;
+	for i=1:length(colorlevels)
+		levels(i+1)=colorlevels{i};
+	end
+	levels(end)=Max;
+	levels=sort(unique(levels));
+	numcolors=length(levels)-1;
+end
+
+%create colorind for colors
+colorind=ones(length(u),1);
+for i=1:numcolors
+	pos=find((Norm>=levels(i)) & (Norm<=levels(i+1)) );
+	colorind(pos)=i;
+end
+colorind(find(Norm>levels(end)))=numcolors;
+
+%build output
+quivers=struct('x',x,'y',y,'u',u,'v',v,'levels',levels,'colorind',colorind,'numcolors',numcolors);
+
+%set the colormap 
+if numcolors==2;
+	%blue and red
+	palette=colormap([0 0 1;1 0 0]);
+elseif numcolors==3,
+	%blue yellow and red
+	palette=colormap([0 0 1;1 1 0;1 0 0]);
+else
+	%let jet choose
+	palette=colormap(jet(numcolors));
+end
Index: /issm/trunk/src/m/model/plot/scaleruler.m
===================================================================
--- /issm/trunk/src/m/model/plot/scaleruler.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/scaleruler.m	(revision 5901)
@@ -0,0 +1,61 @@
+function scaleruler(options)
+%SCALERULER - overlay a scale ruler on current plot
+%
+%   Usage:
+%      scaleruler(options)
+
+%get options
+structure=getfieldvalue(options,'scaleruler');
+fontsize=getfieldvalue(options,'fontsize',16);
+
+%Go through structure and fill missing arguments
+if length(structure)~=5
+	error('plotmodel error message: bad number of input arguments for scaleruler: [x0 y0 length thickness numberofticks]');
+end
+
+%retrieve north arrow parameters
+x0=structure(1);
+y0=structure(2);
+lengthscale=structure(3);
+widthscale=structure(4);
+numberofticks=structure(5);
+
+%initialize some coordinates
+unitlength=lengthscale/(numberofticks -1);
+flag=-1;
+
+Bd=[x0 y0];
+Bu=[x0 y0+widthscale];
+Tick=0;
+
+%Text
+xt=Bu(1);
+yt=Bu(2)+2*widthscale;
+text(xt,yt,num2str(Tick),'FontSize',fontsize,'FontWeight','b');
+
+%loope over the patches
+for i=1:numberofticks-1,
+	Au=Bu;
+	Ad=Bd;
+	Bu=[Au(1)+unitlength Ad(2)+widthscale];
+	Bd=[Ad(1)+unitlength Ad(2)];
+	Tick=Tick+unitlength;
+
+	%pathes
+	if flag==-1
+		p=patch([Ad(1) Bd(1) Bu(1) Au(1)],[Ad(2) Bd(2) Bu(2) Au(2)],'Black','FaceAlpha',0.5);
+	else
+		p=patch([Ad(1) Bd(1) Bu(1) Au(1)],[Ad(2) Bd(2) Bu(2) Au(2)],'White','FaceAlpha',0.3);
+	end
+
+	%flip flag
+	flag=-flag;
+
+	%Text
+	xt=Bu(1);
+	yt=Bu(2)+2*widthscale;
+	if i~=numberofticks-1,
+		text(xt,yt,num2str(round_ice(Tick/1000,3)),'FontSize',fontsize,'FontWeight','b');
+	end
+end
+text(xt,yt,[num2str(round_ice(Tick/1000,3)) ' km'],'FontSize',fontsize,'FontWeight','b');
Index: /issm/trunk/src/m/model/plot/undoplot.m
===================================================================
--- /issm/trunk/src/m/model/plot/undoplot.m	(revision 5901)
+++ /issm/trunk/src/m/model/plot/undoplot.m	(revision 5901)
@@ -0,0 +1,36 @@
+function  undoplot(n)
+%UNDOPLOT - undo plot
+%
+%   o n>0 removes the last n figure items added
+%   o n<0 removes all the figures done after figure=-n
+%   undoplot to remove only the last figure
+%
+%   Usage:
+%      undoplot(n)
+
+%some checks on n
+if nargin==0
+	n=1;
+end
+if ischar(n)
+	n = sscanf(n,'%i');
+end
+
+%how many plots have been done?
+g=get(gca,'children');
+L=length(g);
+
+
+if n>0
+	%erase plot
+	for i=1:min(n,L)
+		delete(g(i));
+	end
+end
+
+if n<0
+	%erase plot
+	for i=1:min(L-n,L)
+		delete(g(i));
+	end
+end
Index: /issm/trunk/src/m/model/plug.m
===================================================================
--- /issm/trunk/src/m/model/plug.m	(revision 5901)
+++ /issm/trunk/src/m/model/plug.m	(revision 5901)
@@ -0,0 +1,38 @@
+function md=plug(md,field,value)
+%PLUG - plugs the holes of a model field
+%
+%   This routine takes a model field interpolated on a mesh, and plugs the holes (made of value)
+%   to the nearest interpolation
+%
+%   Usage:
+%      md=plug(md,field,value)
+
+%First retrieve field
+fieldvalues=eval(['md.' field]);
+
+if isnan(value),
+	holevalues=find(isnan(fieldvalues));
+elseif isinf(value),
+	holevalues=find(isinf(fieldvalues));
+else
+	holevalues=find(fieldvalues==value);
+end
+
+for i=1:length(holevalues),
+
+	index=holevalues(i);
+
+	if ~mod(i,100),
+		%disp(['Step ' num2str(i) '/' num2str(length(holevalues))]);
+	end
+
+	distance=sqrt( (md.x(index)-md.x).^2 + (md.y(index)-md.y).^2 );
+	distance(holevalues)=10^10; %be sure we are not picking up the nan grids!
+
+	index2=find(distance==min(distance));index2=index2(1);
+
+	fieldvalues(index)=fieldvalues(index2);
+end
+
+%Set fieldvalues in md.field
+eval(['md.' field '=fieldvalues;']);
Index: /issm/trunk/src/m/model/plugvelocitiesraw.m
===================================================================
--- /issm/trunk/src/m/model/plugvelocitiesraw.m	(revision 5901)
+++ /issm/trunk/src/m/model/plugvelocitiesraw.m	(revision 5901)
@@ -0,0 +1,98 @@
+function md=plugvelocitiesraw(md,filename,default_value)
+%PLUGVELOCITIESRAW - load raw velocities on a model
+%
+%   load a matlab file (extension .mat) which holds 4 variables
+%   x,y,vx,vy to be plugged onto the model (or similar names)
+%   x and y must be vectors, vx, vy matrices
+%
+%   Usage:
+%      md=plugvelocitiesraw(md,filename,default_value)
+%
+%   Example:
+%      md=plugvelocitiesraw(md,'velocityfile.mat',0);
+%
+%   See also: PLUGVELOCITIES INTERPFROMFILE, GRIDDATA
+
+%some checks
+if nargin~=3 | nargout~=1
+	help plugvelocitiesraw
+	error('plugvelocitiesraw error message: bad usage');
+end
+if ~exist(filename)
+	error(['plugvelocitiesraw error message: file ' filename  ' does not exist']);
+end
+
+%Get variables
+A=whos('-file',filename);
+
+%find x,y,vx and vy
+xenum=NaN; yenum=NaN; vxenum=NaN; vyenum=NaN;
+if length(A)==4,
+	for i=1:4
+		if strcmpi(A(i).name(1),'x');
+			xenum=i;
+		elseif strcmpi(A(i).name(1),'y');
+			yenum=i;
+		else
+			if strcmpi(A(i).name(end),'x');
+				vxenum=i;
+			elseif strcmpi(A(i).name(end),'y');
+				vyenum=i;
+			end
+		end
+	end
+else
+	error(['plugvelocitiesraw error message: file ' filename  ' not supported yet (it should hold 4 variables x,y,vx and vy)']);
+end
+
+%assum that we have found at least vxenum and vyenum
+if ( isnan(vxenum) | isnan(vyenum))
+	error(['plugvelocitiesraw error message: file ' filename  ' not supported yet (it should hold 4 variables x,y,vx and vy)']);
+end
+
+%find x y
+if (isnan(xenum) | isnan(yenum))
+
+	%check the size
+	if A(vxenum).size(1)==A(vxenum).size(2),
+		error(['plugvelocitiesraw error message: file ' filename  ' not supported (velocities is a square matrix, save x and y with another name)']);
+	end
+	if ~(A(vxenum).size(1)==A(vyenum).size(1) & A(vxenum).size(2)==A(vyenum).size(2)),
+		error(['plugvelocitiesraw error message: file ' filename  ' not supported (vx and vy matrices do not have the same size)']);
+	end
+
+	%find xenum and yenum
+	for i=1:4
+		lengthi=max(A(i).size);
+		if ((i~=vxenum) & (lengthi==A(vxenum).size(1) | lengthi==A(vxenum).size(1)+1)),
+			yenum=i;
+		elseif ((i~=vxenum) & (lengthi==A(vxenum).size(2) | lengthi==A(vxenum).size(2)+1)),
+			xenum=i;
+		end
+	end
+
+	%last check
+	if (isnan(xenum) | isnan(yenum))
+		error(['plugdata error message: file ' filename  ' not supported yet']);
+	end
+end
+
+%create names:
+xname=A(xenum).name;
+yname=A(yenum).name;
+vxname=A(vxenum).name;
+vyname=A(vyenum).name;
+
+%load data
+B=load(filename);
+
+%get x y vx and vy
+eval(['x=B.' xname ';'])
+eval(['y=B.' yname ';'])
+eval(['vx=B.' vxname ';'])
+eval(['vy=B.' vyname ';'])
+
+%interpolate
+md.vx_obs_raw=InterpFromGridToMesh(x,y,vx,md.x,md.y,default_value);
+md.vy_obs_raw=InterpFromGridToMesh(x,y,vy,md.x,md.y,default_value);
+md.vel_obs_raw=sqrt(md.vx_obs_raw.^2+md.vy_obs_raw.^2);
Index: /issm/trunk/src/m/model/postsolveparallel.m
===================================================================
--- /issm/trunk/src/m/model/postsolveparallel.m	(revision 5901)
+++ /issm/trunk/src/m/model/postsolveparallel.m	(revision 5901)
@@ -0,0 +1,37 @@
+function md=postsolveparallel(md)
+%POSTSOLVEPARALLEL - postre-solve phase operations for parallel jobs.
+%
+%   Usage:
+%      md=postsolveparallel(md)
+
+
+%errlog: 
+if(md.mem_debug),
+
+	%dump file so we can apply the error_process.sh script to it, then reload onto md.errlog.
+	writefile([md.name '.errlog'],md.errlog);
+
+	%apply error_process.sh
+	system(['errlog_process.sh ' md.name '.errlog']);
+
+	%figure out memory used: 
+	[result,string]=system(['cat ' md.name '.errlog | grep  "definitely lost:"  | awk ''{printf("%s ",$4);}'' | sed ''s/,//g''']);
+	memoryleaks.definitely_lost=str2num(string);
+
+	[result,string]=system(['cat ' md.name '.errlog | grep  "indirectly lost:"  | awk ''{printf("%s",$4);}''| sed ''s/,//g''']);
+	memoryleaks.indirectly_lost=str2num(string);
+
+	[result,string]=system(['cat ' md.name '.errlog | grep  "possibly lost:"  | awk ''{printf("%s",$4);}''| sed ''s/,//g''']);
+	memoryleaks.possibly_lost=str2num(string);
+
+	%reread onto md.errlog
+	try,
+		md.errlog=char(textread([md.name '.errlog'],'%s','delimiter','\n','bufsize',1000000));
+	catch me,
+		disp('postsolveparallel: captured textread error, errlog is too large to read!');
+		md.errlog=''; %too big to read
+	end
+	md.memoryleaks=memoryleaks;
+
+end
+
Index: /issm/trunk/src/m/model/presolve.m
===================================================================
--- /issm/trunk/src/m/model/presolve.m	(revision 5901)
+++ /issm/trunk/src/m/model/presolve.m	(revision 5901)
@@ -0,0 +1,34 @@
+function md=presolve(md)
+%PRESOLVE - pre-solve phase operations.
+%
+%   Usage:
+%      md=presolve(md)
+
+%deal with outputfilename and inputfilename
+md.inputfilename=[md.name '.bin'];
+md.outputfilename=[md.name '.outbin'];
+
+%deal with rifts.
+if isempty(md.rifts) | isnans(md.rifts),
+	md.numrifts=0;
+else
+	md.numrifts=numel(md.rifts);
+end
+
+numpairs=0;
+for i=1:md.numrifts,
+	numpairs=numpairs+size(md.rifts(i).penaltypairs,1);
+end
+
+md.riftinfo=zeros(numpairs,10); % 2 for grids + 2 for elements+ 2 for  normals + 1 for length + 1 for fill + 1 for friction + 1 for fraction.
+
+count=1;
+for i=1:md.numrifts,
+	numpairsforthisrift=size(md.rifts(i).penaltypairs,1);
+	md.riftinfo(count:count+numpairsforthisrift-1,1:7)=md.rifts(i).penaltypairs;
+	md.riftinfo(count:count+numpairsforthisrift-1,8)=md.rifts(i).fill;
+	md.riftinfo(count:count+numpairsforthisrift-1,9)=md.rifts(i).friction;
+	md.riftinfo(count:count+numpairsforthisrift-1,10)=md.rifts(i).fraction;
+	md.riftinfo(count:count+numpairsforthisrift-1,11)=md.rifts(i).fractionincrement;
+	count=count+numpairsforthisrift;
+end
Index: /issm/trunk/src/m/model/printmodel.m
===================================================================
--- /issm/trunk/src/m/model/printmodel.m	(revision 5901)
+++ /issm/trunk/src/m/model/printmodel.m	(revision 5901)
@@ -0,0 +1,100 @@
+function printmodel(filename,format,varargin)
+%PRINTMODEL - save an image of current figure
+%
+%   filename: output name of image file (no extension)
+%   format: image format (ex: 'tiff','jpg','pdf') 
+%
+%   List of options to printfmodel: 
+%
+%   figure: number of figure to print (default: current figure)
+%   resolution: use higher resolution to anti-alias (default 2)
+%   margin: add margin around final image  
+%   marginsize: size of margin around final image (default 5)
+%   frame: add frame around final image
+%   framesize: size of frame around final image (default 5)
+%   framecolor: color of frame around final image (default 'black')
+%   trim: trim empty space around image (default 'off')
+%   hardcopy: 'off' to impose MATLAB to use the same colors (default 'on')
+%   
+%   Usage:
+%      printmodel(filename,format,varargin);
+%
+%   Examples:
+%      printmodel('image','tiff')
+%      printmodel('image','eps','margin','on','frame','on','hardcopy','on')
+
+
+%get options: 
+options=pairoptions(varargin{:});
+
+%set defaults
+options=addfielddefault(options,'figure','gcf');
+options=addfielddefault(options,'format','tiff');
+options=addfielddefault(options,'resolution',2);
+options=addfielddefault(options,'margin','on');
+options=addfielddefault(options,'marginsize',5);
+options=addfielddefault(options,'frame','on');
+options=addfielddefault(options,'framesize',5);
+options=addfielddefault(options,'framecolor','black');
+options=addfielddefault(options,'trim','on');
+options=addfielddefault(options,'hardcopy','on');
+
+%get fig: 
+fig=getfieldvalue(options,'figure');
+if ischar(fig),
+	fig=gcf;
+else
+	figure(fig);
+	fig=gcf;
+end
+
+%In auto mode, MATLAB prints the figure the same size as it appears on the computer screen, centered on the page
+set(fig, 'PaperPositionMode', 'auto');
+
+%InvertHardcopy off imposes MATLAB to use the same colors
+set(fig, 'InvertHardcopy', getfieldvalue(options,'hardcopy'));
+
+
+%we could have several formats, as a cell array of strings.
+formats=format;
+if ~iscell(formats),
+	formats={formats};
+end
+
+%loop on formats:
+for i=1:length(formats),
+	format=formats{i};
+
+	%Use higher resolution to anti-alias and use zbuffer to have smooth colors
+	print(fig, '-zbuffer','-dtiff',['-r' num2str(get(0,'ScreenPixelsPerInch')*getfieldvalue(options,'resolution'))],filename);
+
+	%some trimming involved? 
+	if ~strcmpi(format,'pdf'),
+		if strcmpi(getfieldvalue(options,'trim'),'on'),
+			system(['convert -trim ' filename '.tif ' filename '.tif']);
+		end
+	end
+
+	%margin?
+	if ~strcmpi(format,'pdf'),
+		if strcmpi(getfieldvalue(options,'margin'),'on'),
+			marginsize=getfieldvalue(options,'marginsize');
+			system(['convert -border ' num2str(marginsize) 'x' num2str(marginsize) ' -bordercolor "white" ' filename '.tif ' filename '.tif']);
+		end
+	end
+
+	%frame?
+	if ~strcmpi(format,'pdf'),
+		if strcmpi(getfieldvalue(options,'frame'),'on'),
+			framesize=getfieldvalue(options,'framesize');
+			framecolor=getfieldvalue(options,'framecolor');
+			system(['convert -border ' num2str(framesize) 'x' num2str(framesize) ' -bordercolor "' framecolor '" ' filename '.tif ' filename '.tif']);
+		end
+	end
+
+	%convert image to correct format
+	if ~strcmpi(format,'tiff') & ~strcmpi(format,'tif'),
+		system(['convert ' filename '.tif ' filename '.' format]);
+		delete([ filename '.tif']);
+	end
+end
Index: /issm/trunk/src/m/model/process_solve_options.m
===================================================================
--- /issm/trunk/src/m/model/process_solve_options.m	(revision 5901)
+++ /issm/trunk/src/m/model/process_solve_options.m	(revision 5901)
@@ -0,0 +1,45 @@
+function outoptions=process_solve_options(options)
+%DEFAULT_SOLVE_OPTIONS - set up default options for solve phase
+%
+%   Usage:
+%      options=process_solve_options(options)
+%
+%   See also: SOLVE
+
+%analysis_type: check on this option, error out otherwise
+analysis_type=getfieldvalue(options,'analysis_type');
+
+%sub_analysis_type: check on it, not mandatory
+sub_analysis_type=getfieldvalue(options,'sub_analysis_type',NoneAnalysisEnum);
+
+%batch mode for launching jobs.
+outoptions.batch=getfieldvalue(options,'batch','no');
+
+%directory 
+outoptions.directory=getfieldvalue(options,'directory','');
+
+%convert to Enum if a string was provided
+if ischar(analysis_type), error(['only Enums are supported as ''analysis_type''. For example: md=solve(md,''analysis_type'',DiagnosticSolutionEnum); ']); end
+if ischar(sub_analysis_type), error(['only Enums are supported as ''sub_analysis_type''. For example: md=solve(md,''analysis_type'',DiagnosticSolutionEnum); ']); end
+
+%check solution type is supported
+if ~ismember(analysis_type,[DiagnosticSolutionEnum,PrognosticSolutionEnum,ThermalSolutionEnum,...
+		SteadystateSolutionEnum,ParametersSolutionEnum,Transient2DSolutionEnum,Transient3DSolutionEnum...
+		BalancedthicknessSolutionEnum,BalancedvelocitiesSolutionEnum,BedSlopeSolutionEnum,SurfaceSlopeSolutionEnum]),
+	error(['process_solve_options error message: analysis_type ' EnumToString(analysis_type) ' not supported yet!']);
+end
+if ~ismember(sub_analysis_type,[SteadyAnalysisEnum,NoneAnalysisEnum,HorizAnalysisEnum,GradientAnalysisEnum,InverseAnalysisEnum,VertAnalysisEnum,TransientAnalysisEnum]),
+	error(['process_solve_options error message: sub_analysis_type ' sub_analysis_type ' not supported yet!']);
+end
+outoptions.analysis_type=analysis_type;
+outoptions.sub_analysis_type=sub_analysis_type;
+
+%  process qmu arguments
+outoptions.qmudir=getfieldvalue(options,'qmudir',['qmu' num2str(GetPId)]);  % qmudir =['qmu_' datestr(now,'yyyymmdd_HHMMSS')];
+outoptions.qmufile=getfieldvalue(options,'qmufile','qmu');% qmufile cannot be changed unless ????script.sh is also changed
+outoptions.overwrite=getfieldvalue(options,'overwrite','n');
+outoptions.ivar=getfieldvalue(options,'ivar',1);
+outoptions.iresp=getfieldvalue(options,'iresp',1);
+outoptions.imethod=getfieldvalue(options,'imethod',1);
+outoptions.iparams=getfieldvalue(options,'iparams',1);
+outoptions.runmpi=getfieldvalue(options,'runmpi',false);
Index: /issm/trunk/src/m/model/processgeometry.m
===================================================================
--- /issm/trunk/src/m/model/processgeometry.m	(revision 5901)
+++ /issm/trunk/src/m/model/processgeometry.m	(revision 5901)
@@ -0,0 +1,140 @@
+function geom=processgeometry(geom,tol,outline);
+
+%Deal with edges
+disp('Checking Edge crossing...');
+i=0;
+while (i<size(geom.Edges,1)),
+
+	%edge counter
+	i=i+1;
+
+	%Get coordinates
+	x1=geom.Vertices(geom.Edges(i,1),1);
+	y1=geom.Vertices(geom.Edges(i,1),2);
+	x2=geom.Vertices(geom.Edges(i,2),1);
+	y2=geom.Vertices(geom.Edges(i,2),2);
+	color1=geom.Edges(i,3);
+
+	j=i; %test edges located AFTER i only
+	while (j<size(geom.Edges,1)),
+
+		%edge counter
+		j=j+1;
+
+		%Skip if the two edges already have a vertex in common
+		if any(ismember(geom.Edges(i,1:2),geom.Edges(j,1:2))),
+			continue
+		end
+
+		%Get coordinates
+		x3=geom.Vertices(geom.Edges(j,1),1);
+		y3=geom.Vertices(geom.Edges(j,1),2);
+		x4=geom.Vertices(geom.Edges(j,2),1);
+		y4=geom.Vertices(geom.Edges(j,2),2);
+		color2=geom.Edges(j,3);
+
+		%Check if the two edges are crossing one another
+		if SegIntersect([x1 y1; x2 y2],[x3 y3; x4 y4]),
+
+			%Get coordinate of intersection point (http://mathworld.wolfram.com/Line-LineIntersection.html)
+			x=det([det([x1 y1; x2 y2])  x1-x2;det([x3 y3; x4 y4])  x3-x4])/det([x1-x2 y1-y2;x3-x4 y3-y4]);
+			y=det([det([x1 y1; x2 y2])  y1-y2;det([x3 y3; x4 y4])  y3-y4])/det([x1-x2 y1-y2;x3-x4 y3-y4]);
+
+			%Add vertex to the list of vertices
+			geom.Vertices(end+1,:)=[x y min(color1,color2)];
+			id=size(geom.Vertices,1);
+
+			%Update edges i and j
+			edgei=geom.Edges(i,:);
+			edgej=geom.Edges(j,:);
+			geom.Edges(i,:)    =[edgei(1) id       edgei(3)];
+			geom.Edges(end+1,:)=[id       edgei(2) edgei(3)];
+			geom.Edges(j,:)    =[edgej(1) id       edgej(3)];
+			geom.Edges(end+1,:)=[id       edgej(2) edgej(3)];
+
+			%update current edge second tip
+			x2=x; y2=y;
+		end
+	end
+
+end
+
+%Check point outside
+disp('Checking for points outside the domain...');
+i=0;
+num=0;
+while (i<size(geom.Vertices,1)),
+
+	%vertex counter
+	i=i+1;
+
+	%Get coordinates
+	x=geom.Vertices(i,1);
+	y=geom.Vertices(i,2);
+	color=geom.Vertices(i,3);
+
+	%Check that the point is inside the domain
+	if (color~=1 & ~ContourToNodes(x,y,outline(1),1)),
+
+		%Remove points from list of Vertices
+		num=num+1;
+		geom.Vertices(i,:)=[];
+
+		%update edges
+		[posedges dummy]=find(geom.Edges==i);
+		geom.Edges(posedges,:)=[];
+		posedges=find(geom.Edges>i);
+		geom.Edges(posedges)=geom.Edges(posedges)-1;
+
+		%update counter
+		i=i-1;
+	end
+end
+if num,
+	disp(['WARNING: ' num2str(num) ' points outside the domain outline have been removed']);
+end
+
+%Check point spacing
+if ~isnan(tol),
+	disp('Checking point spacing...');
+	i=0;
+	while (i<size(geom.Vertices,1)),
+
+		%vertex counter
+		i=i+1;
+
+		%Get coordinates
+		x1=geom.Vertices(i,1);
+		y1=geom.Vertices(i,2);
+
+		j=i; %test edges located AFTER i only
+		while (j<size(geom.Vertices,1)),
+
+			%vertex counter
+			j=j+1;
+
+			%Get coordinates
+			x2=geom.Vertices(j,1);
+			y2=geom.Vertices(j,2);
+
+			%Check whether the two vertices are too close
+			if ((x2-x1)^2+(y2-y1)^2<tol^2)
+
+				%Remove points from list of Vertices
+				geom.Vertices(j,:)=[];
+
+				%update edges
+				posedges=find(ismember(geom.Edges,j));
+				geom.Edges(posedges)=i;
+				posedges=find(geom.Edges>j);
+				geom.Edges(posedges)=geom.Edges(posedges)-1;
+
+				%update counter
+				j=j-1;
+
+			end
+		end
+	end
+end
+%remove empty edges
+geom.Edges(find(geom.Edges(:,1)==geom.Edges(:,2)),:)=[];
Index: /issm/trunk/src/m/model/project2d.m
===================================================================
--- /issm/trunk/src/m/model/project2d.m	(revision 5901)
+++ /issm/trunk/src/m/model/project2d.m	(revision 5901)
@@ -0,0 +1,38 @@
+function projection_value=project2d(md3d,value,layer)
+%PROJECT2D - returns the value of a field for a given layer of the mesh
+%
+%   project 'value' vector taken at layer 'layer' from extruded 2d-3d mesh onto 2d mesh 
+%   used to do the extrusion. This routine is used to compare values between a 2d-3d mesh
+%   at a certain layer, and the equivalent value (if it exists), on the original 2d mesh. 
+%   This routine relies heavily on projections (contained in 3d model md) recored during 
+%   the extrude operation.
+%
+%   Usage:
+%      projection_value=project2d(md3d,value,layer)
+%
+%   Example:
+%      vel2=project2d(md3d,md3d.vel,2);
+
+%some checks on list of arguments
+if ((nargin~=3) ),
+	help project2d
+	error('project2d error message');
+end
+
+if md3d.counter<4,
+	error('this model has not been extruded! ... exiting');
+end
+
+if (md3d.dim~=3),
+	error('wrong model type ... should be ''3d''');
+end
+
+if ((layer<1) | (layer>md3d.numlayers)),
+	error(['layer must be between 1 and ' num2str(md3d.numlayers)]);
+end
+
+if size(value,1)==md3d.numberofgrids,
+	projection_value=value((layer-1)*md3d.numberofgrids2d+1:layer*md3d.numberofgrids2d,:);
+else
+	projection_value=value((layer-1)*md3d.numberofelements2d+1:layer*md3d.numberofelements2d,:);
+end
Index: /issm/trunk/src/m/model/project3d.m
===================================================================
--- /issm/trunk/src/m/model/project3d.m	(revision 5901)
+++ /issm/trunk/src/m/model/project3d.m	(revision 5901)
@@ -0,0 +1,46 @@
+function projected_vector=project3d(md3d,vector2d,type,varargin);
+%PROJECT3D - vertically project a vector from 2d mesh
+%
+%   vertically project a vector from 2d mesh (split in noncoll and coll areas) into a 3d mesh.
+%   This vector can be a grid vector of size (md3d.numberofgrids2d,N/A) or an 
+%   element vector of size (md3d.numberofelements2d,N/A). 
+%   type is 'element' or 'node'. layer an optional layer number where vector 
+%   should keep its values. If not specified, all layers adopt the value of the 
+%   2d vector.
+%
+%   Usage:
+%      extruded_vector=project3d(md3d,vector2d,type,layer);
+
+if nargin==4,
+	layer=varargin{1};
+	if ((layer<1) || (layer>md3d.numlayers)),
+		error(['project3d error message: layer shoud be between 1 and ' num2str(md3d.numlayers)]);
+	end
+else
+	layer=0;
+end
+
+if strcmpi(type,'node'),
+
+	projected_vector=zeros(md3d.numberofgrids,size(vector2d,2));
+	
+	if layer==0,
+		for i=1:md3d.numlayers,
+			projected_vector(((i-1)*md3d.numberofgrids2d+1):(i*md3d.numberofgrids2d),:)=vector2d;
+		end
+	else
+		projected_vector(((layer-1)*md3d.numberofgrids2d+1):(layer*md3d.numberofgrids2d),:)=vector2d;
+	end
+else
+
+	projected_vector=zeros(md3d.numberofelements,size(vector2d,2));
+
+	if layer==0,
+		for i=1:(md3d.numlayers-1),
+			projected_vector( ((i-1)*md3d.numberofelements2d+1):(i*md3d.numberofelements2d),:)=vector2d;
+		end
+
+	else
+		projected_vector( ((layer-1)*md3d.numberofelements2d+1):(layer*md3d.numberofelements2d),:)=vector2d;
+	end
+end
Index: /issm/trunk/src/m/model/qpr.m
===================================================================
--- /issm/trunk/src/m/model/qpr.m	(revision 5901)
+++ /issm/trunk/src/m/model/qpr.m	(revision 5901)
@@ -0,0 +1,7 @@
+function qpr(name,format)
+%QPR: quick print of a model
+%
+% Usage: qpr(name,format)
+
+printmodel(name,format,'trim','on','resolution',1,'margin','on','marginsize',25,'frame','on','framesize',3);
+
Index: /issm/trunk/src/m/model/qstat.m
===================================================================
--- /issm/trunk/src/m/model/qstat.m	(revision 5901)
+++ /issm/trunk/src/m/model/qstat.m	(revision 5901)
@@ -0,0 +1,8 @@
+function qstat(md)
+%QSTAT - check job status on remote cluster
+%
+%   Usage:
+%      qstat(md)
+
+%run qstat command on remote cluster
+issmssh(md.cluster,['qstat -a']);
Index: /issm/trunk/src/m/model/queue/BuildQueueingScript.m
===================================================================
--- /issm/trunk/src/m/model/queue/BuildQueueingScript.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/BuildQueueingScript.m	(revision 5901)
@@ -0,0 +1,22 @@
+function BuildQueueingScript(md,executionpath,codepath)
+%BUILDQUEUEINGSCRIPT - Create queueing script
+%
+%   Usage:
+%      BuildQueueingScript(md,executionpath,codepath)
+
+disp('check queue requirements');
+QueueRequirements(md.cluster,md.queue,md.np,md.time);
+
+disp('write queueing script');
+
+%open file 
+fid=fopen([md.name '.queue'],'w');
+if fid==-1,
+	error(['BuildQueueingScript error message: could not open ' [md.name '.queue'] ' file for ascii writing']);
+end
+
+%hand down to cluster specific script
+ClusterScript(fid,md.cluster,md.name,md.queue,executionpath,codepath,md.analysis_type,md.np,md.time,md.mem_debug);
+
+%close file
+fclose(fid);
Index: /issm/trunk/src/m/model/queue/ClusterLaunchCommand.m
===================================================================
--- /issm/trunk/src/m/model/queue/ClusterLaunchCommand.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/ClusterLaunchCommand.m	(revision 5901)
@@ -0,0 +1,22 @@
+function command=ClusterLaunchCommand(cluster,runtimename,name,executionpath)
+%CLUSTERLAUNCHCOMMAND: build command to launch job on cluster
+%
+%    Usage: command=ClusterLaunchCommand(cluster,executionpath)
+
+
+%if cluster is current hostname, just source queue file
+if strcmpi(oshostname(),cluster),
+	command=['cd ' executionpath ' && rm -rf ./' runtimename ' && mkdir ' runtimename ' && cd ' runtimename ' && mv ../' runtimename '.tar.gz ./ && tar -zxf ' runtimename '.tar.gz  && source  ' name '.queue '];
+elseif strcmpi(cluster,'cosmos'),
+	command=['cd ' executionpath ' && rm -rf ./' runtimename ' && mkdir ' runtimename ' && cd ' runtimename ' && mv ../' runtimename '.tar.gz ./ && tar -zxf ' runtimename '.tar.gz  && qsub -S/bin/sh ' name '.queue '];
+elseif strcmpi(cluster,'gemini'),
+	command=['cd ' executionpath ' && rm -rf ./' runtimename ' && mkdir ' runtimename ' && cd ' runtimename ' && mv ../' runtimename '.tar.gz ./ && tar -zxf ' runtimename '.tar.gz  && qsub ' name '.queue '];
+elseif strcmpi(cluster,'pollux'),
+	command=['cd ' executionpath ' && rm -rf ./' runtimename ' && mkdir ' runtimename ' && cd ' runtimename ' && mv ../' runtimename '.tar.gz ./ && tar -zxf ' runtimename '.tar.gz  && qsub ' name '.queue '];
+elseif strcmpi(cluster,'castor'),
+	command=['cd ' executionpath ' && rm -rf ./' runtimename ' && mkdir ' runtimename ' && cd ' runtimename ' && mv ../' runtimename '.tar.gz ./ && tar -zxf ' runtimename '.tar.gz  && qsub ' name '.queue '];
+elseif strcmpi(cluster,'pfe'),
+	command=['cd ' executionpath ' && rm -rf ./' runtimename ' && mkdir ' runtimename ' && cd ' runtimename ' && mv ../' runtimename '.tar.gz ./ && tar -zxf ' runtimename '.tar.gz  && qsub ' name '.queue '];
+else
+	error('ClusterLaunchCommand error message: unknown cluster command');
+end
Index: /issm/trunk/src/m/model/queue/ClusterParameters.m
===================================================================
--- /issm/trunk/src/m/model/queue/ClusterParameters.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/ClusterParameters.m	(revision 5901)
@@ -0,0 +1,115 @@
+function [cluster_codepath cluster_executionpath cluster_login cluster_port]=ClusterParameters(cluster_name,cluster_rc_location)
+%CLUSTERPARAMETERS - from cluster_name, find out cluster parameters in cluster.rc file
+%
+%   This function reads through the cluster_rc_location file  for cluster settings (name,  
+%   code location, execution directory) used to run parallel solution sequences
+%
+%   Usage:
+%      [cluster_codepath cluster_executionpath cluster_login ]=ClusterParameters(cluster_name,cluster_rc_location)
+
+lines_per_cluster=5;
+
+%open cluster.rc file
+
+fid=fopen(cluster_rc_location);
+if fid==-1,
+	error('Could not find cluster.rc file in delivery directory');
+end
+
+found=0;
+
+%Read first line and check it starts with begin. 
+line=fgetl(fid);
+if ~strcmp(line,'begin'),
+	error('cluster.rc file in delivery directory should always start with the begin statement');
+end
+
+%Read until we find the end statement. 
+while 1
+	line=fgetl(fid);
+	
+	%Check for 'end' statement
+	if strcmp(line,'end'),
+		break;
+	end 
+	%Check for end of file
+	if ~ischar(line),
+		error('cluster.rc file in delivery directory should end with an end statement');
+	end
+	%Ignore empty lines
+	if length(line)==0,
+		continue;
+	end
+	%Ignore comments
+	if strcmp(line(1),'#'),
+		continue
+	end
+
+	%Handle cluster name: 
+	if length(line)>12,
+		if strcmp(line(1:12),'cluster_name'),
+			%ok, the next 3 lines deal with one cluster settings.
+			%check if this is the cluster we are looking for.
+			splittedstring=strsplit(line,'=');
+			this_cluster_name=splittedstring{2};
+			if strcmp(this_cluster_name,cluster_name),
+
+				%Get next line for cluster code path
+				line=fgetl(fid);
+				splittedstring=strsplit(line,'=');
+				descriptor=splittedstring{1};
+				value=splittedstring{2};
+				if ~strcmp(descriptor,'cluster_codepath'),
+					error('cluster settings in cluster.rc don''t follow the correct syntax');
+				end
+				cluster_codepath=value;
+				found=1;
+				
+				
+				%Get next line for cluster execution path
+				line=fgetl(fid);
+				splittedstring=strsplit(line,'=');
+				descriptor=splittedstring{1};
+				value=splittedstring{2};
+				if ~strcmp(descriptor,'cluster_executionpath'),
+					error('cluster settings in cluster.rc don''t follow the correct syntax');
+				end
+				cluster_executionpath=value;
+
+				%Get next line for cluster loging name
+				line=fgetl(fid);
+				splittedstring=strsplit(line,'=');
+				descriptor=splittedstring{1};
+				value=splittedstring{2};
+				if ~strcmp(descriptor,'cluster_login'),
+					error('cluster settings in cluster.rc don''t follow the correct syntax');
+				end
+				cluster_login=value;
+
+				%Get next line for cluster port
+				line=fgetl(fid);
+				splittedstring=strsplit(line,'=');
+				descriptor=splittedstring{1};
+				value=splittedstring{2};
+				if ~strcmp(descriptor,'cluster_port'),
+					error('cluster settings in cluster.rc don''t follow the correct syntax');
+				end
+				cluster_port=str2num(value);
+			else
+				%Wrong cluster name, skip next lines_per_cluster lines and continue;
+				for i=1:lines_per_cluster,
+					line=fgetl(fid);
+				end
+				continue;
+			end
+		end
+	end
+end
+
+fclose(fid);
+
+if found==0,
+	error(['ClusterParameters error message: could not find setting for cluster ' cluster_name ' in cluster.rc file']);
+end
+
+end %close of function
Index: /issm/trunk/src/m/model/queue/ClusterScript.m
===================================================================
--- /issm/trunk/src/m/model/queue/ClusterScript.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/ClusterScript.m	(revision 5901)
@@ -0,0 +1,94 @@
+function ClusterScript(fid,cluster,name,queue,executionpath,codepath,analysis_type,np,time,mem_debug);
+%CLUSTERSCRIPT cluster specific queuing script
+%
+% Usage:
+%      ClusterScript(fid,name,queue,executionpath,codepath,analysis_type,np,time);
+%
+global ISSM_DIR;
+
+if strcmpi(cluster,'cosmos'), % {{{1
+
+	fprintf(fid,'#!/bin/bash\n');
+	fprintf(fid,'#PBS -l select=%i:ncpus=1\n',np);
+	fprintf(fid,'#PBS -N %s\n',name);
+	fprintf(fid,'#PBS -l walltime=%i\n',time*60); %walltime is in seconds.
+	fprintf(fid,'#PBS -q %s\n',queue);
+	fprintf(fid,'#PBS -o %s.outlog \n',name);
+	fprintf(fid,'#PBS -e %s.errlog \n',name);
+	fprintf(fid,'export PBS_O_WORKDIR=%s\n',executionpath);
+	fprintf(fid,'cd $PBS_O_WORKDIR\n');
+	fprintf(fid,'export OMP_NUM_THREADS=1\n');
+	fprintf(fid,'ulimit -s unlimited\n');
+	fprintf(fid,'ulimit -c 0\n');
+	fprintf(fid,'/opt/mpich/gm/intel10.1/bin/mpirun -np %i %s/issm.exe %s %s %s.bin %s.outbin %s.lock',np,codepath,EnumToString(analysis_type),executionpath,name,name,name);
+
+	% }}}
+elseif (strcmpi(cluster,'astrid') | strcmpi(cluster,'larsen') | strcmpi(cluster,'wilkes')), % {{{
+
+	fprintf(fid,'#!/bin/sh\n');
+	if mem_debug==0,
+		fprintf(fid,'mpirun -np %i %s/issm.exe %s %s %s.bin %s.outbin %s.lock  2> %s.errlog >%s.outlog & ',np,codepath,EnumToString(analysis_type),executionpath,name,name,name,name,name);
+	else
+		%fprintf(fid,'LD_PRELOAD=%s mpirun -np %i %s --leak-check=full --gen-suppressions=all --suppressions=%s %s/issm.exe %s %s %s.bin %s.outbin %s.lock  2> %s.errlog >%s.outlog & ',[ISSM_DIR '/externalpackages/valgrind/install/lib/libmpidebug.so'],np,[ISSM_DIR '/externalpackages/valgrind/install/bin/valgrind'],[ISSM_DIR '/externalpackages/valgrind/issm.supp'], codepath,EnumToString(analysis_type),executionpath,name,name,name,name,name);
+		fprintf(fid,'LD_PRELOAD=%s mpirun -np %i %s --leak-check=full --suppressions=%s %s/issm.exe %s %s %s.bin %s.outbin %s.lock  2> %s.errlog >%s.outlog & ',[ISSM_DIR '/externalpackages/valgrind/install/lib/libmpidebug.so'],np,[ISSM_DIR '/externalpackages/valgrind/install/bin/valgrind'],[ISSM_DIR '/externalpackages/valgrind/issm.supp'], codepath,EnumToString(analysis_type),executionpath,name,name,name,name,name);
+	end
+
+	% }}}
+elseif (strcmpi(cluster,'eric-mac')), %{{{
+
+	fprintf(fid,'#!/bin/sh\n');
+	if mem_debug==0,
+		fprintf(fid,'mpirun -np %i %s/issm.exe %s %s %s.bin %s.outbin %s.lock  2> %s.errlog >%s.outlog & ',np,codepath,EnumToString(analysis_type),executionpath,name,name,name,name,name);
+	else
+		%fprintf(fid,'LD_PRELOAD=%s mpirun -np %i %s --leak-check=full --gen-suppressions=all --suppressions=%s %s/issm.exe %s %s %s.bin %s.outbin %s.lock  2> %s.errlog >%s.outlog & ',[ISSM_DIR '/externalpackages/valgrind/install/lib/libmpidebug.so'],np,[ISSM_DIR '/externalpackages/valgrind/install/bin/valgrind'],[ISSM_DIR '/externalpackages/valgrind/issm.supp'], codepath,EnumToString(analysis_type),executionpath,name,name,name,name,name);
+		fprintf(fid,'LD_PRELOAD=%s mpirun -np %i %s --leak-check=full --suppressions=%s %s/issm.exe %s %s %s.bin %s.outbin %s.lock  2> %s.errlog >%s.outlog & ',[ISSM_DIR '/externalpackages/valgrind/install/lib/libmpidebug.so'],np,[ISSM_DIR '/externalpackages/valgrind/install/bin/valgrind'],[ISSM_DIR '/externalpackages/valgrind/issm.supp'], codepath,EnumToString(analysis_type),executionpath,name,name,name,name,name);
+	end
+
+	% }}}
+elseif (strcmpi(cluster,'gemini') | strcmpi(cluster,'pollux') | strcmpi(cluster,'castor')), % {{{1
+
+	fprintf(fid,'#!/bin/sh\n');
+	fprintf(fid,'#PBS -l walltime=%i\n',time*60); %walltime is in seconds.
+	fprintf(fid,'#PBS -N %s\n',name);
+	fprintf(fid,'#PBS -l ncpus=%i\n',np);
+	if ~isempty(queue),
+		fprintf(fid,'#PBS -q %s\n',queue);
+	end
+	fprintf(fid,'#PBS -o %s.outlog \n',name);
+	fprintf(fid,'#PBS -e %s.errlog \n',name);
+
+	fprintf(fid,'export PBS_O_WORKDIR=%s\n',executionpath);
+	fprintf(fid,'cd $PBS_O_WORKDIR\n');
+	fprintf(fid,'export OMP_NUM_THREADS=1\n');
+	fprintf(fid,'dplace -s1 -c0-%i mpirun -np %i %s/issm.exe %s %s %s.bin %s.outbin %s.lock',np-1,np,codepath,EnumToString(analysis_type),executionpath,name,name,name);
+
+	% }}}
+elseif strcmpi(cluster,'pfe'), % {{{1
+
+	fprintf(fid,'#PBS -S /bin/bash\n');
+	fprintf(fid,'#PBS -N %s\n',name);
+	fprintf(fid,'#PBS -l select=%i:ncpus=8:model=neh\n',np/8);
+	fprintf(fid,'#PBS -l walltime=%i\n',time*60); %walltime is in seconds.
+	fprintf(fid,'#PBS -W group_list=s1010\n');
+	fprintf(fid,'#PBS -m e\n');
+	fprintf(fid,'#PBS -o %s.outlog \n',name);
+	fprintf(fid,'#PBS -e %s.errlog \n\n',name);
+
+	fprintf(fid,'. /usr/share/modules/init/bash\n\n');
+
+	fprintf(fid,'module load comp-intel/11.1.046\n');
+	fprintf(fid,'module load mpi/mpt.1.25\n');
+	fprintf(fid,'module load math/intel_mkl_64_10.0.011\n\n');
+
+	fprintf(fid,'export PATH="$PATH:."\n\n');
+	fprintf(fid,'export MPI_GROUP_MAX=64\n\n');
+
+	fprintf(fid,'cd $PBS_O_WORKDIR\n\n');
+
+	fprintf(fid,'mpiexec -verbose -np %i %s/issm.exe %s $PBS_O_WORKDIR %s.bin %s.outbin %s.lock',np,codepath,EnumToString(analysis_type),name,name,name);
+
+	% }}}
+else % {{{1
+	error(['ClusterScript error message: could not find settings for cluster ' cluster]);
+end
+% }}}
Index: /issm/trunk/src/m/model/queue/LaunchQueueJob.m
===================================================================
--- /issm/trunk/src/m/model/queue/LaunchQueueJob.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/LaunchQueueJob.m	(revision 5901)
@@ -0,0 +1,39 @@
+function md=LaunchQueueJob(md,executionpath,login,port,options)
+%LAUNCHQUEUEJOB- Launch queue script for cluster
+%
+%   Usage:
+%      md=LaunchQueueJob(md,executionpath,launchcommand,login,port,options)
+
+
+%first, check we have the binary file and the queueing script
+if ~exist([ md.name '.bin'],'file'),
+	error('LaunchQueueJobcosmos error message: Binary input file missing, cannot go forward');
+end
+
+if ~exist([ md.name '.queue'],'file'),
+	error('LaunchQueueJobcosmos error message: queueing script missing, cannot go forward');
+end
+
+if md.qmu_analysis & ~exist([ md.name '.qmu.in'],'file'),
+	error('LaunchQueueJobcosmos error message: missing dakota input file, cannot go forward');
+end
+
+if ~strcmpi(options.batch,'yes'),
+	
+	%compress the files into one zip.
+	compressstring=['tar -zcf ' md.runtimename '.tar.gz ' md.name '.bin ' md.name '.queue '];
+	if md.qmu_analysis,
+		compressstring=[compressstring md.name '.qmu.in'];
+	end
+	system(compressstring);
+	
+	disp('uploading input file and queueing script');
+	issmscpout(md.cluster,executionpath,login,port,{[md.runtimename '.tar.gz']});
+
+	disp('launching solution sequence on remote cluster');
+	issmssh(md.cluster,login,port,ClusterLaunchCommand(md.cluster,md.runtimename,md.name,executionpath));
+
+else
+	disp('batch mode requested: not launching job interactively');
+	disp('launch solution sequence on remote cluster by hand');
+end
Index: /issm/trunk/src/m/model/queue/QueueRequirements.m
===================================================================
--- /issm/trunk/src/m/model/queue/QueueRequirements.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/QueueRequirements.m	(revision 5901)
@@ -0,0 +1,126 @@
+function QueueRequirements(cluster,queue,np,time)
+%QUEUEREQUIREMENTS queue requirements in time, number of cpus, by name of queue.
+%
+%
+% Usage: QueueRequirements(cluster,queue,np,time)
+%
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%cluster settings%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+if strcmpi(cluster,'cosmos'),
+
+	available_queues={'debug','shortq','longq','specialq'};
+	queue_requirements_time=[60*1 60*3 60*17 1440];
+	queue_requirements_np=[32 128 256 256];
+	queue_requirements_modulo=[1 1 1 1];
+
+elseif strcmpi(cluster,'gemini'),
+
+	available_queues={'debug','shortg','longg'};
+	queue_requirements_time=[60 180 720];
+	queue_requirements_np=[50 50 50];
+	queue_requirements_modulo=[1 1 1 ];
+
+elseif strcmpi(cluster,'castor'),
+
+	available_queues={'shortc','longc'};
+	queue_requirements_time=[180 720];
+	queue_requirements_np=[128 128];
+	queue_requirements_modulo=[1 1 ];
+
+elseif strcmpi(cluster,'pollux'),
+
+	available_queues={'shortp','longp'};
+	queue_requirements_time=[180 720];
+	queue_requirements_np=[128 128];
+	queue_requirements_modulo=[1 1 ];
+
+elseif strcmpi(cluster,'astrid'),
+
+	available_queues={'none'};
+	queue_requirements_time=[Inf];
+	queue_requirements_np=[16];
+	queue_requirements_modulo=[1 ];
+
+elseif strcmpi(cluster,'eric-mac'),
+
+	available_queues={'none'};
+	queue_requirements_time=[Inf];
+	queue_requirements_np=[4];
+	queue_requirements_modulo=[1 ];
+
+elseif strcmpi(cluster,'larsen'),
+
+	available_queues={'none'};
+	queue_requirements_time=[Inf];
+	queue_requirements_np=[8];
+	queue_requirements_modulo=[1 ];
+
+elseif strcmpi(cluster,'wilkes'),
+
+	available_queues={'none'};
+	queue_requirements_time=[Inf];
+	queue_requirements_np=[16];
+	queue_requirements_modulo=[1 ];
+
+elseif strcmpi(cluster,'pfe'),
+
+	available_queues={'long'};
+	queue_requirements_time=[7200];
+	queue_requirements_np=[2048];
+	queue_requirements_modulo=[8 ];
+
+else
+	error(['BuildQueueingScript error message: cannot find requirements for ' cluster ]);
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%end settings%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%Ok, go through requirements for current queue:
+index=ismemberi(queue,available_queues);
+if  ~index,
+	%ok, either we a generic cluster, with 'none' queue, or we could not find the queue reqruirements
+	if strcmpi(available_queues{1},'none'),
+		%reset index to 1, so we can fish the requirements
+		index=1;
+	else
+		string=available_queues{1};
+		for i=2:length(available_queues),
+			string=[string ' ' available_queues{i}];
+		end
+		error(['QueueRequirements error message: availables queues are ' string]);
+	end
+end
+
+%check on time requirements
+rtime=queue_requirements_time(index);
+
+if time<=0,
+	error('QueueRequirements: time should be a positive number');
+end
+
+if time>rtime,
+	error(['QueueRequirements: time should be < ' num2str(rtime) ' for queue: ' queue]);
+end
+
+%check on np requirements
+rnp=queue_requirements_np(index);
+rmod=queue_requirements_modulo(index);
+
+if np<=0,
+	error('QueueRequirements: np should be a positive number');
+end
+
+if np>rnp,
+	error(['QueueRequirements: np should be < ' num2str(rnp) ' for queue: ' queue]);
+end
+
+%check np is a multiple of the queue multiple 
+if mod(np,rmod),
+	error(['QueueRequirements: np should be a multiple of ' num2str(rmod) ' for queue: ' queue]);
+end
Index: /issm/trunk/src/m/model/queue/multiple/BuildMultipleQueueingScript.m
===================================================================
--- /issm/trunk/src/m/model/queue/multiple/BuildMultipleQueueingScript.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/multiple/BuildMultipleQueueingScript.m	(revision 5901)
@@ -0,0 +1,23 @@
+function BuildMultipleQueueingScript(cluster,name,executionpath,codepath)
+%BUILDMULTIPLEQUEUEINGSCRIPT - 
+%
+%   Usage:
+%      BuildMultipleQueueingScript(executionpath,codepath)
+
+disp('building queueing script');
+
+%First try and figure out if there is a special script for this particular cluster
+function_name=['BuildMultipleQueueingScript' cluster];
+
+%some specific treatment of identical cluster, gemini, castor and pollux
+if strcmpi(cluster,'castor') || strcmpi(cluster,'pollux'),
+	function_name='BuildMultipleQueueingScriptgemini';
+end
+
+if exist(function_name,'file'),
+	%Call this function:
+	eval([function_name '(name,executionpath,codepath);']);
+else
+	%Call the generic BuildQueueingScript:
+	BuildMultipleQueueingScriptGeneric(name,executionpath,codepath);
+end
Index: /issm/trunk/src/m/model/queue/multiple/BuildMultipleQueueingScriptGeneric.m
===================================================================
--- /issm/trunk/src/m/model/queue/multiple/BuildMultipleQueueingScriptGeneric.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/multiple/BuildMultipleQueueingScriptGeneric.m	(revision 5901)
@@ -0,0 +1,12 @@
+function BuildMultipleQueueingScriptGeneric(name,executionpath,codepath)
+%BUILDMULTIPLEQUEUEINGSCRIPTGENERIC - ...
+%
+%   Usage:
+%      BuildMultipleQueueingScriptGeneric(executionpath,codepath)
+
+global ISSM_DIR
+
+
+%not done yet
+error('BuildMultipleQueueingScriptGenericerror message: not supported yet!');
+
Index: /issm/trunk/src/m/model/queue/multiple/BuildMultipleQueueingScriptgemini.m
===================================================================
--- /issm/trunk/src/m/model/queue/multiple/BuildMultipleQueueingScriptgemini.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/multiple/BuildMultipleQueueingScriptgemini.m	(revision 5901)
@@ -0,0 +1,23 @@
+function BuildQueueingScriptgemini(name,executionpath,codepath)
+%BUILDQUEUEINGSCRIPTGEMINI - ...
+%
+%   Usage:
+%      BuildQueueingScriptgemini(md,executionpath,codepath)
+
+scriptname=[name '.queue'];
+
+fid=fopen(scriptname,'w');
+if fid==-1,
+	error(['BuildQueueingScriptgeminierror message: could not open ' scriptname ' file for ascii writing']);
+end
+
+fprintf(fid,'#!/bin/sh\n');
+fprintf(fid,'cd %s\n',executionpath);
+fprintf(fid,'mkdir %s\n',name);
+fprintf(fid,'cd %s\n',name);
+fprintf(fid,'mv ../ModelList.tar.gz ./\n');
+fprintf(fid,'tar -zxvf ModelList.tar.gz\n');
+fprintf(fid,'foreach i (%s-*vs*.queue)\n',name);
+fprintf(fid,'qsub $i\n');
+fprintf(fid,'end\n');
+fclose(fid);
Index: /issm/trunk/src/m/model/queue/multiple/LaunchMultipleQueueJob.m
===================================================================
--- /issm/trunk/src/m/model/queue/multiple/LaunchMultipleQueueJob.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/multiple/LaunchMultipleQueueJob.m	(revision 5901)
@@ -0,0 +1,21 @@
+function LaunchMultipleQueueJob(cluster,name,executionpath)
+%LAUNCHMULTIPLEQUEUEJOB - ...
+%
+%   Usage:
+%      LaunchMultipleQueueJob(executionpath)
+
+%First try and figure out if there is a special script for thie particular cluster
+function_name=['LaunchMultipleQueueJob' cluster];
+
+%some specific treatment of identical cluster, gemini, castor and pollux
+if strcmpi(cluster,'castor') || strcmpi(cluster,'pollux'),
+	function_name='LaunchMultipleQueueJobgemini';
+end
+
+if exist(function_name,'file'),
+	%Call this function:
+	eval([function_name '(cluster,name,executionpath);']);
+else
+	%Call the generic LaunchMultipleQueueJob:
+	LaunchMultipleQueueJobGeneric(cluster,name,executionpath);
+end
Index: /issm/trunk/src/m/model/queue/multiple/LaunchMultipleQueueJobGeneric.m
===================================================================
--- /issm/trunk/src/m/model/queue/multiple/LaunchMultipleQueueJobGeneric.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/multiple/LaunchMultipleQueueJobGeneric.m	(revision 5901)
@@ -0,0 +1,7 @@
+function LaunchMultipleQueueJobGeneric(cluster,name,executionpath)
+%LAUNCHMULTIPLEQUEUEJOBGENERIC - Generic routine to launch multiple queueing job
+%
+%   Usage:
+%      LaunchMultipleQueueJobGeneric(cluster,name,executionpath)
+
+error('LaunchMultipleQueueJobGeneric error message: not supported yet!');
Index: /issm/trunk/src/m/model/queue/multiple/LaunchMultipleQueueJobgemini.m
===================================================================
--- /issm/trunk/src/m/model/queue/multiple/LaunchMultipleQueueJobgemini.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/multiple/LaunchMultipleQueueJobgemini.m	(revision 5901)
@@ -0,0 +1,22 @@
+function md=LaunchMultipleQueueJobgemini(cluster,name,executionpath)
+%LAUNCHMULTIPLEQUEUEJOBGEMINI - Launch multiple queueing script on Gemini cluster
+%
+%   Usage:
+%      LaunchMultipleQueueJobgemini(cluster,name,executionpath)
+
+
+%first, check we have the binary file and the queueing script
+if ~exist([ name '.queue'],'file'),
+	error('LaunchMultipleQueueJobgemini error message: queueing script issing, cannot go forward');
+end
+
+if ~exist('ModelList.tar.gz','file'),
+	error('LaunchMultipleQueueJobgemini error message: inputs models file missing, cannot go forward');
+end
+
+%upload both files to cluster
+disp('uploading input file,  queueing script and variables script');
+eval(['!scp ModelList.tar.gz ' name '.queue '  cluster ':' executionpath]);
+
+disp('launching solution sequence on remote cluster');
+issmssh(cluster,login,['"cd ' executionpath ' && source ' name '.queue "']);
Index: /issm/trunk/src/m/model/queue/old/BuildQueueingScriptGeneric.m
===================================================================
--- /issm/trunk/src/m/model/queue/old/BuildQueueingScriptGeneric.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/old/BuildQueueingScriptGeneric.m	(revision 5901)
@@ -0,0 +1,26 @@
+function BuildQueueingScriptGeneric(md,executionpath,codepath)
+%BUILDQUEUEINGSCRIPTGENERIC - ...
+%
+%   Usage:
+%      BuildQueueingScriptGeneric(md,executionpath,codepath)
+
+global ISSM_DIR
+
+%Open queuing script file 
+scriptname=[md.name '.queue'];
+
+fid=fopen(scriptname,'w');
+if fid==-1,
+	error(['BuildQueueingScriptGenericerror message: could not open ' scriptname ' file for ascii writing']);
+end
+
+fprintf(fid,'#!/bin/sh\n');
+fprintf(fid,'rm -rf %s/%s.lock\n',executionpath,md.name);
+
+if md.mem_debug==0,
+fprintf(fid,'mpirun -np %i %s/%s.exe %s %s.bin %s.outbin %s.lock  2> %s.errlog >%s.outlog & ',md.np,codepath,EnumToString(md.analysis_type),executionpath,md.name,md.name,md.name,md.name,md.name);
+else
+fprintf(fid,'LD_PRELOAD=%s mpirun -np %i %s --leak-check=full %s/%s.exe %s %s.bin %s.outbin %s.lock  2> %s.errlog >%s.outlog & ',[ISSM_DIR '/externalpackages/valgrind/install/lib/libmpidebug.so'],md.np,[ISSM_DIR '/externalpackages/valgrind/install/bin/valgrind'],codepath,EnumToString(md.analysis_type),executionpath,md.name,md.name,md.name,md.name,md.name);
+end
+
+fclose(fid);
Index: /issm/trunk/src/m/model/queue/old/BuildQueueingScriptcosmos.m
===================================================================
--- /issm/trunk/src/m/model/queue/old/BuildQueueingScriptcosmos.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/old/BuildQueueingScriptcosmos.m	(revision 5901)
@@ -0,0 +1,22 @@
+function BuildQueueingScriptcosmos(md,executionpath,codepath)
+%BUILDQUEUEINGSCRIPTGEMINI - ...
+%
+%   Usage:
+%      BuildQueueingScriptcosmos(md,executionpath,codepath)
+
+
+fprintf(fid,'#!/bin/bash\n');
+fprintf(fid,'#PBS -l select=%i:ncpus=1\n',md.np);
+fprintf(fid,'#PBS -l walltime=%i\n',md.time*60); %walltime is in seconds.
+fprintf(fid,'#PBS -q %s\n',md.queue);
+fprintf(fid,'#PBS -o %s.outlog \n',md.name);
+fprintf(fid,'#PBS -e %s.errlog \n',md.name);
+fprintf(fid,'export PBS_O_WORKDIR=%s\n',executionpath);
+fprintf(fid,'cd $PBS_O_WORKDIR\n');
+fprintf(fid,'export OMP_NUM_THREADS=1\n');
+fprintf(fid,'ulimit -s unlimited\n');
+fprintf(fid,'ulimit -c 0\n');
+fprintf(fid,'/opt/mpich/gm/intel10.1/bin/mpirun -np %i %s/%s.exe %s %s.bin %s.outbin %s.lock',md.np,codepath,EnumToString(md.analysis_type),executionpath,md.name,md.name,md.name);
+
+
+fclose(fid);
Index: /issm/trunk/src/m/model/queue/old/BuildQueueingScriptgemini.m
===================================================================
--- /issm/trunk/src/m/model/queue/old/BuildQueueingScriptgemini.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/old/BuildQueueingScriptgemini.m	(revision 5901)
@@ -0,0 +1,22 @@
+function BuildQueueingScriptgemini(md,executionpath,codepath)
+%BUILDQUEUEINGSCRIPTGEMINI - ...
+%
+%   Usage:
+%      BuildQueueingScriptgemini(md,executionpath,codepath)
+
+scriptname=[md.name '.queue'];
+fprintf(fid,'#!/bin/sh\n');
+fprintf(fid,'#PBS -l walltime=%i\n',md.time*60); %walltime is in seconds.
+fprintf(fid,'#PBS -l ncpus=%i\n',md.np);
+if ~isempty(md.queue),
+	fprintf(fid,'#PBS -q %s\n',md.queue);
+end
+fprintf(fid,'#PBS -o %s.outlog \n',md.name);
+fprintf(fid,'#PBS -e %s.errlog \n',md.name);
+
+fprintf(fid,'export PBS_O_WORKDIR=%s\n',executionpath);
+fprintf(fid,'cd $PBS_O_WORKDIR\n');
+fprintf(fid,'export OMP_NUM_THREADS=1\n');
+fprintf(fid,'dplace -s1 -c0-%i mpirun -np %i %s/%s.exe %s %s.bin %s.outbin %s.lock',md.np-1,md.np,codepath,EnumToString(md.analysis_type),executionpath,md.name,md.name,md.name);
+
+fclose(fid);
Index: /issm/trunk/src/m/model/queue/old/BuildQueueingScriptgreenplanet.m
===================================================================
--- /issm/trunk/src/m/model/queue/old/BuildQueueingScriptgreenplanet.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/old/BuildQueueingScriptgreenplanet.m	(revision 5901)
@@ -0,0 +1,21 @@
+function BuildQueueingScriptgreenplanet(md,executionpath,codepath)
+%BUILDQUEUEINGSCRIPTGEMINI - ...
+%
+%   Usage:
+%      BuildQueueingScriptgreenplanet(md,executionpath,codepath)
+
+scriptname=[md.name '.queue'];
+
+
+fprintf(fid,'#!/bin/csh\n');
+fprintf(fid,'#PBS -N %s\n',md.name);
+fprintf(fid,'#PBS -l nodes=%i:ppn=%i\n',md.np/8,8);
+fprintf(fid,'#PBS -q %s\n',md.queue);
+fprintf(fid,'#PBS -m bea\n');
+fprintf(fid,'#PBS -M eric.larour@jpl.nasa.gov\n');
+fprintf(fid,'#PBS -l walltime=%i\n',md.time*60); %walltime is in seconds.
+
+fprintf(fid,'cd $PBS_O_WORKDIR\n');
+fprintf(fid,'mpirun -machinefile $PBS_NODEFILE -np %i %s/%s.exe %s %s.bin %s.outbin %s.lock > %s.outlog',md.np,codepath,EnumToString(md.analysis_type),executionpath,md.name,md.name,md.name,md.name);
+
+fclose(fid);
Index: /issm/trunk/src/m/model/queue/old/BuildQueueingScriptpfe.m
===================================================================
--- /issm/trunk/src/m/model/queue/old/BuildQueueingScriptpfe.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/old/BuildQueueingScriptpfe.m	(revision 5901)
@@ -0,0 +1,49 @@
+function BuildQueueingScriptpfe(md,executionpath,codepath)
+%BUILDQUEUEINGSCRIPTPFE - ...
+%
+%   Usage:
+%      BuildQueueingScriptpfe(md,executionpath,codepath)
+
+scriptname=[md.name '.queue'];
+
+
+	available_queues={'long'};
+	if  ~ismemberi(md.queue,available_queues),
+	end
+	if md.time>720,
+		error('BuildQueueingScriptcosmos error message: long queue only allows 720 minutes');
+	end
+	if mod(md.np,8),
+		error('BuildQueueingScriptcosmos error message: np should be a multiple of 8');
+	end
+
+end
+
+fid=fopen(scriptname,'w');
+if fid==-1,
+	error(['BuildQueueingScriptpfeerror message: could not open ' scriptname ' file for ascii writing']);
+end
+
+
+fprintf(fid,'#PBS -S /bin/bash\n');
+fprintf(fid,'#PBS -N %s\n',md.name);
+fprintf(fid,'#PBS -l select=%i:ncpus=8:mpiprocs=8\n',md.np/8);
+fprintf(fid,'#PBS -l walltime=%i\n',md.time*60); %walltime is in seconds.
+fprintf(fid,'#PBS -W group_list=s1010\n');
+fprintf(fid,'#PBS -m e\n');
+fprintf(fid,'#PBS -o %s.outlog \n',md.name);
+fprintf(fid,'#PBS -e %s.errlog \n\n',md.name);
+
+fprintf(fid,'. /usr/share/modules/init/bash\n\n');
+
+fprintf(fid,'module load comp-intel/11.1.046\n');
+fprintf(fid,'module load mpi/mpt.1.23.nas\n');
+fprintf(fid,'module load math/intel_mkl_64_10.0.011\n\n');
+
+fprintf(fid,'export PATH="$PATH:."\n\n');
+
+fprintf(fid,'cd $PBS_O_WORKDIR\n\n');
+
+fprintf(fid,'mpiexec -verbose -np %i %s/%s.exe $PBS_O_WORKDIR %s.bin %s.outbin %s.lock',md.np,codepath,EnumToString(md.analysis_type),md.name,md.name,md.name);
+
+fclose(fid);
Index: /issm/trunk/src/m/model/queue/old/LaunchQueueJobGeneric.m
===================================================================
--- /issm/trunk/src/m/model/queue/old/LaunchQueueJobGeneric.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/old/LaunchQueueJobGeneric.m	(revision 5901)
@@ -0,0 +1,34 @@
+function md=LaunchQueueJobGeneric(md,executionpath,options,login,port)
+%LAUNCHQUEUEJOBGENERIC - Generic routine to launch queueing job
+%
+%   Usage:
+%      LaunchQueueJobGeneric(md,executionpath)
+
+%first, check we have the binary file and the queueing script
+if ~exist([ md.name '.bin'],'file'),
+	error('LaunchQueueJobGeneric error message: Binary input file missing, cannot go forward');
+end
+
+if ~exist([ md.name '.queue'],'file'),
+	error('LaunchQueueJobGeneric error message: queueing script issing, cannot go forward');
+end
+
+if ~strcmpi(options.batch,'yes'),
+
+	%what files are we sending?
+	packages={[md.name '.bin'],[md.name '.queue']};
+	if md.qmu_analysis,
+		packages{end+1}=[md.name '.qmu.in'];
+	end
+
+	disp('uploading input file and queueing script');
+	scpout(md.cluster,executionpath,packages);
+	
+	disp('launching solution sequence on remote cluster');
+	issmssh(md.cluster,login,port,['cd ' executionpath ' && source ' md.name '.queue ']);
+
+else
+	disp('batch mode requested: not launching job interactively');
+	disp(['launch solution sequence by copying files ' md.name '.bin' ',' md.name '.queue and ' md.name '.qmu.in, onto remote cluster ' md.cluster]);
+	disp(['   then log int ' md.cluster ' and source queue file ' md.name '.queue']);
+end
Index: /issm/trunk/src/m/model/queue/old/LaunchQueueJobcosmos.m
===================================================================
--- /issm/trunk/src/m/model/queue/old/LaunchQueueJobcosmos.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/old/LaunchQueueJobcosmos.m	(revision 5901)
@@ -0,0 +1,32 @@
+function md=LaunchQueueJobcosmos(md,executionpath,options,login)
+%LAUNCHQUEUEJOBCOSMOS- Launch queue script for Cosmos cluster
+%
+%   Usage:
+%      LaunchQueueJobcosmos(md,executionpath)
+
+%first, check we have the binary file and the queueing script
+if ~exist([ md.name '.bin'],'file'),
+	error('LaunchQueueJobcosmos error message: Binary input file missing, cannot go forward');
+end
+
+if ~exist([ md.name '.queue'],'file'),
+	error('LaunchQueueJobcosmos error message: queueing script issing, cannot go forward');
+end
+
+%jpload both files to cluster
+if ~strcmpi(options.batch,'yes'),
+	disp('uploading input file,  queueing script and variables script');
+	if md.qmu_analysis, 
+		system(['scp ' md.name '.bin' ' ' md.name '.queue '  md.name '.qmu.in ' md.cluster ':' executionpath]);
+	else
+		system(['scp ' md.name '.bin' ' ' md.name '.queue '  md.cluster ':' executionpath]);
+	end
+
+	disp('launching solution sequence on remote cluster');
+	issmssh(md.cluster,login,['"cd ' executionpath ' && qsub -S/bin/sh ' md.name '.queue "']);
+else
+	disp('batch mode requested: not launching job interactively');
+
+	%new gemini cannot launch across cluster using ssh
+	disp(['launch solution sequence on remote cluster by logging into it and typing qsub -S/bin/sh ' md.name '.queue']);
+end
Index: /issm/trunk/src/m/model/queue/old/LaunchQueueJobgemini.m
===================================================================
--- /issm/trunk/src/m/model/queue/old/LaunchQueueJobgemini.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/old/LaunchQueueJobgemini.m	(revision 5901)
@@ -0,0 +1,32 @@
+function md=LaunchQueueJobgemini(md,executionpath,options,login)
+%LAUNCHQUEUEJOBGEMINI - Launch queueing script on Gemini cluster
+%
+%   Usage:
+%      LaunchQueueJobgemini(md,executionpath)
+
+%first, check we have the binary file and the queueing script
+if ~exist([ md.name '.bin'],'file'),
+	error('LaunchQueueJobgemini error message: Binary input file missing, cannot go forward');
+end
+
+if ~exist([ md.name '.queue'],'file'),
+	error('LaunchQueueJobgemini error message: queueing script issing, cannot go forward');
+end
+
+%jpload both files to cluster
+if ~strcmpi(options.batch,'yes'),
+	disp('uploading input file,  queueing script and variables script');
+	if md.qmu_analysis, 
+		system(['scp ' md.name '.bin' ' ' md.name '.queue '  md.name '.qmu.in ' md.cluster ':' executionpath]);
+	else
+		system(['scp ' md.name '.bin' ' ' md.name '.queue '  md.cluster ':' executionpath]);
+	end
+	
+	disp('launching solution sequence on remote cluster');
+	issmssh(md.cluster,login,['"cd ' executionpath ' && qsub ' md.name '.queue "']);
+else
+	disp('batch mode requested: not launching job interactively');
+
+	%new gemini cannot launch across cluster using ssh
+	disp(['launch solution sequence on remote cluster by logging into it and typing qsub < ' md.name '.queue']);
+end
Index: /issm/trunk/src/m/model/queue/old/LaunchQueueJobgreenplanet.m
===================================================================
--- /issm/trunk/src/m/model/queue/old/LaunchQueueJobgreenplanet.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/old/LaunchQueueJobgreenplanet.m	(revision 5901)
@@ -0,0 +1,29 @@
+function md=LaunchQueueJobgreenplanet(md,executionpath,options,login)
+%LAUNCHQUEUEJOBGEMINI - ...
+%
+%   Usage:
+%      LaunchQueueJobgreenplanet(md,executionpath)
+
+%first, check we have the binary file and the queueing script
+if ~exist([ md.name '.bin'],'file'),
+	error('LaunchQueueJobgreenplanet error message: Binary input file missing, cannot go forward');
+end
+
+if ~exist([ md.name '.queue'],'file'),
+	error('LaunchQueueJobgreenplanet error message: queueing script issing, cannot go forward');
+end
+
+%jpload both files to cluster
+if ~strcmpi(options.batch,'yes'),
+	disp('uploading input file,  queueing script and variables script');
+	if md.qmu_analysis, 
+		system(['scp -P 1025 -o HostKeyAlias=huey.jpl.nasa.gov ' md.name '.bin' ' ' md.name '.queue '  md.name '.qmu.in elarour@localhost:' executionpath]);
+	else
+		system(['scp -P 1025 -o HostKeyAlias=huey.jpl.nasa.gov ' md.name '.bin' ' ' md.name '.queue elarour@localhost:' executionpath ]);
+	end
+else
+	disp('batch mode requested: not launching job interactively');
+end
+
+%new greenplanet cannot launch across cluster using ssh
+disp(['launch solution sequence on remote cluster by logging into it and typing qsub < ' md.name '.queue']);
Index: /issm/trunk/src/m/model/queue/old/LaunchQueueJobpfe.m
===================================================================
--- /issm/trunk/src/m/model/queue/old/LaunchQueueJobpfe.m	(revision 5901)
+++ /issm/trunk/src/m/model/queue/old/LaunchQueueJobpfe.m	(revision 5901)
@@ -0,0 +1,32 @@
+function md=LaunchQueueJobpfe(md,executionpath,options,login)
+%LAUNCHQUEUEJOBPFE - Launch queueing script on Gemini cluster
+%
+%   Usage:
+%      LaunchQueueJobpfe(md,executionpath)
+
+%first, check we have the binary file and the queueing script
+if ~exist([ md.name '.bin'],'file'),
+	error('LaunchQueueJobpfe error message: Binary input file missing, cannot go forward');
+end
+
+if ~exist([ md.name '.queue'],'file'),
+	error('LaunchQueueJobpfe error message: queueing script issing, cannot go forward');
+end
+
+%jpload both files to cluster
+if ~strcmpi(options.batch,'yes'),
+	disp('uploading input file,  queueing script and variables script');
+	if md.qmu_analysis, 
+		system(['scp ' md.name '.bin' ' ' md.name '.queue '  md.name '.qmu.in ' login '@' md.cluster ':' executionpath]);
+	else
+		system(['scp ' md.name '.bin' ' ' md.name '.queue '  login '@' md.cluster ':' executionpath]);
+	end
+	
+	disp('launching solution sequence on remote cluster');
+	issmssh(md.cluster,login,['"cd ' executionpath ' && qsub ' md.name '.queue "']);
+else
+	disp('batch mode requested: not launching job interactively');
+
+	%new pfe cannot launch across cluster using ssh
+	disp(['launch solution sequence on remote cluster by logging into it and typing qsub < ' md.name '.queue']);
+end
Index: /issm/trunk/src/m/model/radarpower.m
===================================================================
--- /issm/trunk/src/m/model/radarpower.m	(revision 5901)
+++ /issm/trunk/src/m/model/radarpower.m	(revision 5901)
@@ -0,0 +1,76 @@
+function md=radarpower(md,hemisphere,xlim,ylim,highres)
+%RADARPOWER - overlay a power radar image on an existing mesh
+%
+%   This routine will overlay a power radar image on an existing mesh.
+%   The power amplitude will be output to vel for now.
+%   In the future, think about a field to hold this value.
+%
+%   Usage:
+%      md=radarpower(md,hemisphere,xlim,ylim,highres)
+
+global ISSM_DIR
+global MODELDATA
+
+%if MODELDATA has not been initialized (ie: empty), use default path.
+if isempty(MODELDATA), MODELDATA='/u/astrid-r1b/larour/ModelData'; end
+
+%find gdal coordinates
+x0=min(xlim);
+x1=max(xlim);
+
+y0=min(ylim);
+y1=max(ylim);
+
+%Get path  to gdal binaries
+path_gdal=[ISSM_DIR '/externalpackages/gdal/install/bin/'];
+
+%Was gdal compiled? 
+if ~exist([path_gdal 'gdal_translate']),
+	error(['radarpower error message: GDAL library needs to be compiled to use this routine. Compile GDAL in ' ISSM_DIR '/externalpackages/gdal to use this routine.']);
+end
+
+%the geotiff image is either 200m or 1km accuracy. 
+if strcmpi(hemisphere,'n'),
+	if ~exist([MODELDATA '/MOG/mog150_greenland_map.jpg']),
+		error(['radarpower error message: file ' MODELDATA '/MOG/mog150_greenland_map.jpg not found. Check MODELDATA variable..']);
+	end
+	jpgim=[MODELDATA '/MOG/mog150_greenland_map.jpg'];
+	geom=load([MODELDATA '/MOG/mog150_greenland_map.jpgw'],'ascii');
+	sizex=floor((x1-x0)/geom(1)); % x posting
+	sizey=floor((y1-y0)/geom(4)); % y posting
+	topleftx=floor((x0-geom(5))/geom(1)); % x min
+	toplefty=floor((geom(6)-y1)/geom(4)); % y max
+
+	%Read and crop file
+	im=imread(jpgim);
+	im=im(toplefty:toplefty+sizey,topleftx:topleftx+sizex);
+	md.sarpwr=double(flipud(im));
+	md.sarxm=(x0:(x1-x0)/(size(md.sarpwr,2)-1):x1);
+	md.sarym=(y0:(y1-y0)/(size(md.sarpwr,1)-1):y1);
+
+else
+	if highres,
+		if ~exist([MODELDATA '/MosaicTiffRsat/amm125m_v2_200m.tif']),
+			error(['radarpower error message: file ' MODELDATA '/MosaicTiffRsat/amm125m_v2_200m.tif not found. Check MODELDATA variable..']);
+		end
+		geotiff_name=[MODELDATA '/MosaicTiffRsat/amm125m_v2_200m.tif'];
+	else
+		if ~exist([MODELDATA '/MosaicTiffRsat/amm125m_v2_1km.tif']),
+			error(['radarpower error message: file ' MODELDATA '/MosaicTiffRsat/amm125m_v2_1km.tif not found. Check MODELDATA variable..']);
+		end
+		geotiff_name=[MODELDATA '/MosaicTiffRsat/amm125m_v2_1km.tif'];
+	end
+
+	%Name of image
+	inputname='./temp.tif';
+	system([path_gdal 'gdal_translate -quiet -projwin ' num2str(x0) ' ' num2str(y1) ' ' num2str(x1) ' ' num2str(y0) ' ' geotiff_name ' ' inputname ]);
+
+	%Read in temp.tif:
+	md.sarpwr=double(flipud(imread('temp.tif','TIFF')));
+	md.sarxm=(x0:(x1-x0)/(size(md.sarpwr,2)-1):x1);
+	md.sarym=(y0:(y1-y0)/(size(md.sarpwr,1)-1):y1);
+
+	%Erase image
+	system('rm -rf ./temp.tif');
+
+end
Index: /issm/trunk/src/m/model/recover_areas.m
===================================================================
--- /issm/trunk/src/m/model/recover_areas.m	(revision 5901)
+++ /issm/trunk/src/m/model/recover_areas.m	(revision 5901)
@@ -0,0 +1,23 @@
+function [hutterflag macayealflag pattynflag stokesflag filltype]=recover_areas(md,varargin);
+%RECOVER_AREAS - flag the element depending on the physical model that is assigned to them
+%
+%   This routine is called by setelementstype, do not use
+%
+%   Usage:
+%      [hutterflag macayealflag pattynflag stokesflag filltype]=recover_areas(md,varargin);
+
+	%go through varargin, extract options and plug them into subtype options, by order of appearance
+	options=pairoptions(varargin{:});
+	options=deleteduplicates(options,1);
+
+	%recover elements distribution
+	hutterflag  =FlagElements(md,getfieldvalue(options,'hutter',''));
+	macayealflag=FlagElements(md,getfieldvalue(options,'macayeal',''));
+	pattynflag  =FlagElements(md,getfieldvalue(options,'pattyn',''));
+	stokesflag  =FlagElements(md,getfieldvalue(options,'stokes',''));
+	hutterflag  =FlagElements(md,getfieldvalue(options,'hutter',''));
+	filltype    =getfieldvalue(options,'fill','none');
+
+end %end function
+
+
Index: /issm/trunk/src/m/model/removeholes.m
===================================================================
--- /issm/trunk/src/m/model/removeholes.m	(revision 5901)
+++ /issm/trunk/src/m/model/removeholes.m	(revision 5901)
@@ -0,0 +1,46 @@
+function md2=removeholes(md,field)
+%REMOVEHOLES - interpolate a field on the a mesh without any hole
+%
+%   as its name indicates, this routine takes a model, a field (value of some 
+%   physical quantity evaluated at the mesh grids) of the model, and interpolates this field 
+%   on the model mesh, without any hole.
+%
+%   Usage:
+%      md=removeholes(md,field)
+
+%Check that model is complete
+if md.counter<3,
+	error('removeholes error message: model is incomplete ... exiting');
+end
+
+if nargin~=2,
+	removeholesusage;
+	error('removeholes error message');
+end
+
+if ~ischar(field), 
+	removeholesusage;
+	error('removeholes error message');
+end
+
+%Ok, retrieve and write domain outline without holes, to disk.
+domainoutline_string=md.domainoutline;
+name_slots=findstr(domainoutline_string,'## Name');
+domainoutline_string=domainoutline_string(1:(name_slots(2)-1)); %only keep first outline
+writefile('DomainOutlineTemp.exp',domainoutline_string);
+
+%Now create new model with mesh based on DomainOutlineTemp: 
+%get average resolution
+resolution=mean(sqrt(2*area(md.elements,md.x,md.y)));
+md2=model;
+md2=mesh(md2,'DomainOutlineTemp.exp',resolution);
+
+%Ok, now interpolate field onto this new mesh
+fieldvalue=getfield(md,field);
+md2=setfield(md2,field,griddata(md.x,md.y,fieldvalue,md2.x,md2.y));
+
+end %end of function
+
+function removeholesusage(),
+disp('usage: md2=removeholes(md,field)');
+end
Index: /issm/trunk/src/m/model/setelementstype.m
===================================================================
--- /issm/trunk/src/m/model/setelementstype.m	(revision 5901)
+++ /issm/trunk/src/m/model/setelementstype.m	(revision 5901)
@@ -0,0 +1,211 @@
+function md=setelementstype(md,varargin)
+%SETELEMENTSTYPE - associate a solution type to each element
+%
+%   This routine works like plotmodel: it works with an even number of inputs
+%   'hutter','macayeal','pattyn','stokes' and 'fill' are the possible options
+%   that must be followed by the corresponding exp file or flags list
+%   It can either be a domain file (argus type, .exp extension), or an array of element flags. 
+%   If user wants every element outside the domain to be 
+%   setelementstyped, add '~' to the name of the domain file (ex: '~Pattyn.exp');
+%   an empty string '' will be considered as an empty domain
+%   a string 'all' will be considered as the entire domain
+%   You can specify the type of coupling, 'penalties' or 'tiling', to use with the input 'coupling'
+%
+%   Usage:
+%      md=setelementstype(md,varargin)
+%
+%   Example:
+%      md=setelementstype(md,'pattyn','Pattyn.exp','macayeal',md.elementoniceshelf,'fill','hutter');
+%      md=setelementstype(md,'pattyn','Pattyn.exp',fill','hutter','coupling','tiling');
+
+%some checks on list of arguments
+if ((nargin<2) | (nargout~=1)),
+	error('setelementstype error message');
+end
+
+if md.counter<3,
+	error('only fully parameterized 2d models can be setelementstyped');
+end
+
+%Find_out what kind of coupling to use
+options=pairoptions(varargin{:});
+coupling_method=getfieldvalue(options,'coupling','tiling');
+if (~strcmpi(coupling_method,'tiling') & ~strcmpi(coupling_method,'penalties')),
+	error('coupling type can only be: tiling or penalties');
+end
+
+[hutterflag macayealflag pattynflag stokesflag filltype]=recover_areas(md,varargin{:});
+
+%Flag the elements that has not been flagged as filltype
+if strcmpi(filltype,'hutter'),
+	hutterflag(find(~macayealflag & ~pattynflag))=1;
+elseif strcmpi(filltype,'macayeal'),
+	macayealflag(find(~hutterflag & ~pattynflag))=1;
+elseif strcmpi(filltype,'pattyn'),
+	pattynflag(find(~hutterflag & ~macayealflag & ~stokesflag))=1;
+end
+
+%check that each element has at least one flag
+if any(hutterflag+ macayealflag+pattynflag+stokesflag==0),
+	error('setelementstype error message: elements type not assigned, must be specified')
+end
+
+%check that each element has only one flag
+if any(hutterflag+ macayealflag+pattynflag+stokesflag>1),
+	disp('setelementstype warning message: some elements have several types, higher order type is used for them')
+	hutterflag(find(hutterflag & macayealflag))=0;
+	hutterflag(find(hutterflag & pattynflag))=0;
+	macayealflag(find(macayealflag & pattynflag))=0;
+end
+
+%Check that no pattyn or stokes for 2d mesh
+if (md.dim==2),
+	if any(stokesflag | pattynflag)
+		error('setelementstype error message: stokes and pattyn elements no allowed in 2d mesh, extrude it first')
+	end
+end
+
+%Stokes can only be used alone for now:
+if any(stokesflag) &any(hutterflag+macayealflag),
+	error('setelementstype error message: stokes cannot be used with any other model for now, put stokes everywhere')
+end
+
+%add in model who is who
+md.elements_type=zeros(md.numberofelements,1);
+
+%1: Hutter elements
+gridonhutter=zeros(md.numberofgrids,1);
+gridonhutter(md.elements(find(hutterflag),:))=1;
+md.gridonhutter=gridonhutter;
+md.elements_type(find(hutterflag))=HutterApproximationEnum();
+
+%2: MacAyeal elements
+gridonmacayeal=zeros(md.numberofgrids,1);
+gridonmacayeal(md.elements(find(macayealflag),:))=1;
+md.gridonmacayeal=gridonmacayeal;
+md.elements_type(find(macayealflag))=MacAyealApproximationEnum();
+
+%3: Pattyn elements
+gridonpattyn=zeros(md.numberofgrids,1);
+gridonpattyn(md.elements(find(pattynflag),:))=1;
+md.gridonpattyn=gridonpattyn;
+md.elements_type(find(pattynflag))=PattynApproximationEnum();
+
+%4: Stokes elements
+%First modify stokesflag to get rid of elements contrained everywhere (spc + border with pattyn or macayeal)
+if any(stokesflag),
+	gridonstokes=zeros(md.numberofgrids,1);
+	gridonstokes(md.elements(find(stokesflag),:))=1;
+	fullspcnodes=double(sum(md.spcvelocity(:,1:3),2)==3 | (gridonpattyn & gridonstokes));         %find all the grids on the boundary of the domain without icefront
+	fullspcelems=double(sum(fullspcnodes(md.elements),2)==6);         %find all the grids on the boundary of the domain without icefront
+	stokesflag(find(fullspcelems))=0;
+end
+gridonstokes=zeros(md.numberofgrids,1);
+gridonstokes(md.elements(find(stokesflag),:))=1;
+md.gridonstokes=gridonstokes;
+md.elements_type(find(stokesflag))=StokesApproximationEnum();
+
+%Then complete with NoneApproximation or the other model used if there is no stokes
+if any(stokesflag), 
+	if any(pattynflag), %fill with pattyn
+		pattynflag(~stokesflag)=1;
+		gridonpattyn(md.elements(find(pattynflag),:))=1;
+		md.gridonpattyn=gridonpattyn;
+		md.elements_type(find(~stokesflag))=PattynApproximationEnum();
+	else %fill with none 
+	%5: None elements (non Stokes)
+		md.elements_type(find(~stokesflag))=NoneApproximationEnum();
+	end
+end
+
+%Now take care of the coupling between MacAyeal and Pattyn
+md.penalties=[];
+gridonmacayealpattyn=zeros(md.numberofgrids,1);
+gridonpattynstokes=zeros(md.numberofgrids,1);
+if strcmpi(coupling_method,'penalties'),
+	%Create the border grids between Pattyn and MacAyeal and extrude them
+	numgrids2d=md.numberofgrids2d;
+	numlayers=md.numlayers;
+	bordergrids2d=find(gridonpattyn(1:numgrids2d) & gridonmacayeal(1:numgrids2d)); %Grids connected to two different types of elements
+
+	%initialize and fill in penalties structure
+	if ~isnan(bordergrids2d),
+		penalties=[];
+		for	i=1:numlayers-1,
+			penalties=[penalties; [bordergrids2d bordergrids2d+md.numberofgrids2d*(i)]];
+		end
+		md.penalties=penalties;
+	end
+elseif strcmpi(coupling_method,'tiling'),
+	if any(macayealflag) & any(pattynflag), %coupling macayeal pattyn
+		%Find grid at the border
+		gridonmacayealpattyn(find(gridonmacayeal & gridonpattyn))=1;
+		%Macayeal elements in contact with this layer become MacAyealPattyn elements
+		matrixelements=ismember(md.elements,find(gridonmacayealpattyn));
+		commonelements=sum(matrixelements,2)~=0;
+		commonelements(find(pattynflag))=0; %only one layer: the elements previously in macayeal
+		macayealflag(find(commonelements))=0; %these elements are now macayealpattynelements
+		macayealpattynflag=zeros(md.numberofelements,1);
+		macayealpattynflag(find(commonelements))=1;
+		gridonmacayeal=zeros(md.numberofgrids,1);
+		gridonmacayeal(md.elements(find(macayealflag),:))=1;
+		md.gridonmacayeal=gridonmacayeal;
+
+		%Create MacaAyealPattynApproximation where needed
+		md.elements_type(find(macayealpattynflag))=MacAyealPattynApproximationEnum();
+
+		%Now recreate gridonmacayeal and gridonmacayealpattyn
+		gridonmacayealpattyn(md.elements(find(macayealpattynflag),:))=1;
+	elseif any(pattynflag) & any(stokesflag), %coupling pattyn stokes
+		%Find grid at the border
+		gridonpattynstokes(find(gridonpattyn & gridonstokes))=1;
+		%Stokes elements in contact with this layer become PattynStokes elements
+		matrixelements=ismember(md.elements,find(gridonpattynstokes));
+		commonelements=sum(matrixelements,2)~=0;
+		commonelements(find(pattynflag))=0; %only one layer: the elements previously in macayeal
+		stokesflag(find(commonelements))=0; %these elements are now macayealpattynelements
+		pattynstokesflag=zeros(md.numberofelements,1);
+		pattynstokesflag(find(commonelements))=1;
+		gridonstokes=zeros(md.numberofgrids,1);
+		gridonstokes(md.elements(find(stokesflag),:))=1;
+		md.gridonstokes=gridonstokes;
+
+		%Create MacaAyealPattynApproximation where needed
+		md.elements_type(find(pattynstokesflag))=PattynStokesApproximationEnum();
+
+		%Now recreate gridonmacayeal and gridonmacayealpattyn
+		gridonpattynstokes(md.elements(find(pattynstokesflag),:))=1;
+	elseif any(stokesflag) & any(macayealflag+hutterflag),
+		error('type of coupling not supported yet');
+	end
+end
+
+%Create vertices_type
+md.vertices_type=zeros(md.numberofgrids,1);
+pos=find(gridonhutter);
+md.vertices_type(pos)=HutterApproximationEnum();
+pos=find(gridonmacayeal);
+md.vertices_type(pos)=MacAyealApproximationEnum();
+pos=find(gridonpattyn);
+md.vertices_type(pos)=PattynApproximationEnum();
+pos=find(gridonhutter);
+md.vertices_type(pos)=HutterApproximationEnum();
+pos=find(gridonpattyn & gridonmacayeal);
+md.vertices_type(pos)=PattynApproximationEnum();
+pos=find(gridonmacayealpattyn);
+md.vertices_type(pos)=MacAyealPattynApproximationEnum();
+pos=find(gridonpattynstokes);
+md.vertices_type(pos)=PattynStokesApproximationEnum();
+pos=find(gridonstokes);
+md.vertices_type(pos)=StokesApproximationEnum();
+if any(stokesflag),
+	pos=find(~gridonstokes);
+	md.vertices_type(pos)=NoneApproximationEnum();
+end
+
+%figure out solution types
+md.ishutter=double(any(md.elements_type==HutterApproximationEnum));
+md.ismacayealpattyn=double(any(md.elements_type==MacAyealApproximationEnum | md.elements_type==PattynApproximationEnum));
+md.isstokes=double(any(md.elements_type==StokesApproximationEnum));
+
+end
Index: /issm/trunk/src/m/model/shear2d.m
===================================================================
--- /issm/trunk/src/m/model/shear2d.m	(revision 5901)
+++ /issm/trunk/src/m/model/shear2d.m	(revision 5901)
@@ -0,0 +1,17 @@
+function [sx,sy,sxy,s]=shear2d(md)
+%SHEAR2D - computes 2d strain rate
+%
+%   This routine computes the strain rate of 2d models
+%
+%   Usage:
+%      [sx,sy,sxy,s]=shear2d(md);
+
+[alpha beta]=GetNodalFunctionsCoeff(md.elements,md.x,md.y); 
+
+summation=[1;1;1];
+sx=(md.vx(md.elements).*alpha)*summation;
+uy=(md.vx(md.elements).*beta)*summation;
+vx=(md.vy(md.elements).*alpha)*summation;
+sy=(md.vy(md.elements).*beta)*summation;						
+sxy=(uy+vx)/2;
+s=sqrt(sx.^2+sy.^2+sxy.^2+sx.*sy);
Index: /issm/trunk/src/m/model/shearnorm2d.m
===================================================================
--- /issm/trunk/src/m/model/shearnorm2d.m	(revision 5901)
+++ /issm/trunk/src/m/model/shearnorm2d.m	(revision 5901)
@@ -0,0 +1,9 @@
+function s=shearnorm2d(md)
+%SHEARNORM2D - computes the norm of the strain rate
+%
+%   Usage:
+%      s=shearnorm2d(md)
+%
+%   See also: shear2d
+
+[sx,sy,sxy,s]=shear2d(md);
Index: /issm/trunk/src/m/model/slope.m
===================================================================
--- /issm/trunk/src/m/model/slope.m	(revision 5901)
+++ /issm/trunk/src/m/model/slope.m	(revision 5901)
@@ -0,0 +1,32 @@
+function [sx,sy,s]=slope(md)
+%SLOPE - compute the surface slope
+%
+%   Usage:
+%      [sx,sy,s]=slope(md)
+
+%load some variables (it is much faster if the variab;es are loaded from md once for all) 
+if (md.dim==2),
+	numberofelements=md.numberofelements;
+	numberofgrids=md.numberofgrids;
+	index=md.elements;
+	x=md.x; y=md.y; z=md.z;
+else
+	numberofelements=md.numberofelements2d;
+	numberofgrids=md.numberofgrids2d;
+	index=md.elements2d;
+	x=md.x2d; y=md.y2d; z=md.z2d;
+end
+
+%compute nodal functions coefficients N(x,y)=alpha x + beta y + gamma
+[alpha beta]=GetNodalFunctionsCoeff(index,x,y);
+
+summation=[1;1;1];
+sx=(md.surface(index).*alpha)*summation;
+sy=(md.surface(index).*beta)*summation;
+s=sqrt(sx.^2+sy.^2);
+
+if md.dim==3,
+	sx=project3d(md,sx,'element');
+	sy=project3d(md,sy,'element');
+	s=sqrt(sx.^2+sy.^2);
+end
Index: /issm/trunk/src/m/model/solve.m
===================================================================
--- /issm/trunk/src/m/model/solve.m	(revision 5901)
+++ /issm/trunk/src/m/model/solve.m	(revision 5901)
@@ -0,0 +1,72 @@
+function md=solve(md,varargin)
+%SOLVE - apply solution sequence for this model
+%
+%   Usage:
+%      md=solve(md,varargin)
+%      where varargin is a lit of paired arguments of string OR enums
+%      arguments can be: 'analysis_type': 'DiagnosticAnalysis','ThermalAnalysis','PrognosticAnalysis','Transient2DAnalysis'
+%      arguments can be: 'sub_analysis_type': 'Transient2DAnalysis','SteadyAnalysis','NoneAnalysisEnum'
+%
+%   Examples:
+%      md=solve(md,'analysis_type',DiagnosticSolutionEnum);
+%      md=solve(md,'analysis_type','ThermalAnalysis','sub_analysis_type','Transient2DAnalysis');
+%      md=solve(md,'analysis_type',ThermalSolutionEnum,'sub_analysis_type',SteadyAnalysisEnum);
+%      md=solve(md,'analysis_type','ThermalAnalysis');
+
+%some checks on list of arguments
+global ISSM_DIR
+
+%recover options
+options=pairoptions(varargin{:});
+
+%add default options
+options=process_solve_options(options);
+
+%recover some fields
+md.analysis_type=options.analysis_type;
+md.sub_analysis_type=options.sub_analysis_type;
+
+%check model consistency
+displaystring(md.verbose,'\n%s\n','checking model consistency');
+ismodelselfconsistent(md),
+
+%preprocesses model before solving
+md=presolve(md);
+
+%if running qmu analysis, some preprocessing of dakota files using 
+%models fields needs to be carried out. 
+if md.qmu_analysis,
+	md=preqmu(md,options);
+end
+
+%Save model as is (in case of a crash)
+assignin('base',inputname(1),md);
+
+displaystring(md.verbose,'\n%s\n','launching solution sequence');
+
+%If running in parallel, we have a different way of launching the solution
+%sequences. 
+if ~strcmpi(md.cluster,'none'),
+	md=solveparallel(md,options);
+	return;
+end
+
+%Launch correct solution sequence
+md=issm(md,md.analysis_type);
+
+%post processes qmu results if necessary
+if md.qmu_analysis,
+	md=postqmu(md);
+	cd ..
+	system(['rm -rf qmu' num2str(GetPId)]);
+end
+
+%Check result is consistent
+displaystring(md.verbose,'%s\n','checking result consistency');
+%if ~isresultconsistent(md,options.analysis_type),
+%	disp('!! results not consistent correct the model !!') %it would be very cruel to put an error, it would kill the computed results (even if not consistent...)
+%end
+
+%convert analysis type to string finally
+md.analysis_type=EnumToString(options.analysis_type);
+md.sub_analysis_type=EnumToString(options.sub_analysis_type);
Index: /issm/trunk/src/m/model/solveparallel.m
===================================================================
--- /issm/trunk/src/m/model/solveparallel.m	(revision 5901)
+++ /issm/trunk/src/m/model/solveparallel.m	(revision 5901)
@@ -0,0 +1,51 @@
+function md=solveparallel(md,options)
+%SOLVEPARALLEL - solution sequence using a cluster in parallel mode
+%
+%   Usage:
+%      md=solveparallel(md);
+
+%First, build a runtime name that is unique, that we will use to create 
+%directories, name jobs, etc ...
+c=clock;
+md.runtimename=sprintf('%s-%i-%i-%i-%i-%i-%i',md.name,GetPId,c(2),c(3),c(1),c(4),c(5));
+
+%Get cluster.rc location
+cluster_rc_location=which('cluster.rc');
+
+%Figure out parameters for this particular cluster
+[codepath,executionpath,login,port]=ClusterParameters(md.cluster,cluster_rc_location);
+
+%Marshall model data into a binary file.
+marshall(md);
+
+%add qmu fields to binary file if running qmu analysis
+if md.qmu_analysis,
+	qmumarshall(md,md.variables(options.ivar),md.responses(options.iresp));
+end
+
+%Now, we need to build the queuing script, used by the cluster to launch the job.
+BuildQueueingScript(md,executionpath,codepath);
+
+%Now, launch the queueing script
+md=LaunchQueueJob(md,executionpath,login,port,options);
+
+%Do we return, or just wait for results?
+if (md.waitonlock~=0 &  ~strcmpi(options.batch,'yes')),
+	%we wait for the done file
+	islock=waitonlock(md,executionpath,login,port);
+	if islock==0,
+		%no results to be loaded
+		disp('The results must be loaded manually with md=loadresultsfromcluster(md).');
+	else
+		%load results
+		displaystring(md.verbose,'loading results from cluster');
+		md=loadresultsfromcluster(md);
+	end
+end
+
+%post processes qmu results if necessary
+if md.qmu_analysis,
+	system(['rm -rf qmu' num2str(GetPId)]);
+end
+
+
Index: /issm/trunk/src/m/model/solvers/solversettoasm.m
===================================================================
--- /issm/trunk/src/m/model/solvers/solversettoasm.m	(revision 5901)
+++ /issm/trunk/src/m/model/solvers/solversettoasm.m	(revision 5901)
@@ -0,0 +1,9 @@
+function md=solversettoasm(md)
+%SOLVERSETTOASM - associate solver asm to the model
+%
+%   Usage:
+%      md=solversettoasm(md)
+
+%md.solverstring=' -mat_type aij -ksp_type cgs -pc_type asm -sub_mat_type mumps -sub_pc_type lu -pc_asm_overlap 4 -pc_factor_shift_positive_definite true';
+%md.solverstring=' -mat_type aij -ksp_type cgs -pc_type asm -sub_pc_type lu -pc_asm_overlap 4 ';
+md.solverstring=' -mat_type aij -ksp_type gmres -pc_type asm -sub_pc_type lu -pc_asm_overlap 4 ';
Index: /issm/trunk/src/m/model/solvers/solversettomatlab.m
===================================================================
--- /issm/trunk/src/m/model/solvers/solversettomatlab.m	(revision 5901)
+++ /issm/trunk/src/m/model/solvers/solversettomatlab.m	(revision 5901)
@@ -0,0 +1,7 @@
+function md=solversettomatlab(md)
+%SOLVERSETTOASM - associate solver matlab to the model
+%
+%   Usage:
+%      md=solversettomatlab(md)
+
+md.solverstring='-ksp_type matlab';
Index: /issm/trunk/src/m/model/solvers/solversettomumps.m
===================================================================
--- /issm/trunk/src/m/model/solvers/solversettomumps.m	(revision 5901)
+++ /issm/trunk/src/m/model/solvers/solversettomumps.m	(revision 5901)
@@ -0,0 +1,10 @@
+function md=solversettomumps(md)
+%SOLVERSETTOMUMPS - associate solver mumps to the model
+%
+%   Usage:
+%      md=solversettomumps(md)
+
+md.solverstring='-mat_type aijmumps -ksp_type preonly -pc_type lu -mat_mumps_icntl_14 120 -pc_factor_shift_positive_definite true';
+
+%optional
+%md.solverstring=[md.solverstring ' -mat_mumps_icntl_14 40 -mat_mumps_icntl_4 0 -mat_mumps_sym 1 -mat_ignore_lower_triangular'];
Index: /issm/trunk/src/m/model/solvers/solversettosor.m
===================================================================
--- /issm/trunk/src/m/model/solvers/solversettosor.m	(revision 5901)
+++ /issm/trunk/src/m/model/solvers/solversettosor.m	(revision 5901)
@@ -0,0 +1,10 @@
+function md=solversettosor(md)
+%SOLVERSETTOSOR - associate solver sor to the model
+%
+%   Usage:
+%      md=solversettosor(md)
+
+md.mat_type='aij';
+md.ksp_type='cg';
+md.pc_type='sor';
+md.solver_extra_option=' -pc_sor_omega 1.1 -pc_sor_its 2 ';
Index: /issm/trunk/src/m/model/structtomodel.m
===================================================================
--- /issm/trunk/src/m/model/structtomodel.m	(revision 5901)
+++ /issm/trunk/src/m/model/structtomodel.m	(revision 5901)
@@ -0,0 +1,17 @@
+function md=structtomodel(md,structmd)
+%STRUCTTOMODEL - convert a structure into a model
+%
+%   This function will take all the fields in structmd and copy them to corresponding
+%   fields in the md @model class instance. If the field does not exist in md, it is dropped.
+%
+%   Usage:
+%      md=structtomodel(md,structmd)
+
+structfields=fields(structmd);
+for i=1:length(structfields),
+	field=structfields(i);field=field{1};
+	fieldval=getfield(structmd,field);
+	if isfield(struct(md),field),
+		md=setfield(md,field,fieldval);
+	end
+end
Index: /issm/trunk/src/m/model/thicknessevolution.m
===================================================================
--- /issm/trunk/src/m/model/thicknessevolution.m	(revision 5901)
+++ /issm/trunk/src/m/model/thicknessevolution.m	(revision 5901)
@@ -0,0 +1,28 @@
+function dhdt=thicknessevolution(md)
+%THICKNESSEVOLUTION - compute the new thickness of a model after ∆t
+%
+%   This routine compute the new thickness of a model after a time step
+%   according to the following formula:
+%   dh/dt=-div(Hu)
+%
+%   Usage:
+%      dhdt=thicknessevolution(md)
+
+if (length(md.vx)~=md.numberofgrids)|(length(md.vy)~=md.numberofgrids)
+	error(['thicknessevolution error message: vx and vy should have a length of ' num2str(md.numberofgrids)])
+end
+
+%load some variables 
+H=md.thickness;
+vx=md.vx;
+vy=md.vy;
+index=md.elements;
+
+%compute nodal functions coefficients N(x,y)=alpha x + beta y + gamma
+[alpha beta]=GetNodalFunctionsCoeff(md.elements,md.x,md.y); 
+
+%compute dhdt=div(Hu)
+summation=1/3*ones(3,1);
+dhdt=(vx(index)*summation).*sum( H(index).*alpha,2) + (vy(index)*summation).*sum(H(index).*beta,2) ...
+	+ ( H(index)*summation).*sum(vx(index).*alpha,2) + ( H(index)*summation).*sum(vy(index).*beta,2);
+dhdt=-dhdt;
Index: /issm/trunk/src/m/model/todo
===================================================================
--- /issm/trunk/src/m/model/todo	(revision 5901)
+++ /issm/trunk/src/m/model/todo	(revision 5901)
@@ -0,0 +1,1 @@
+allow optional settings in constructor.
Index: /issm/trunk/src/m/model/tres.m
===================================================================
--- /issm/trunk/src/m/model/tres.m	(revision 5901)
+++ /issm/trunk/src/m/model/tres.m	(revision 5901)
@@ -0,0 +1,70 @@
+function md=tres(md,string)
+%TRES - transfer results results to corresponding model fields. 
+%
+%    Usage: md=tres(md,string)
+%
+%    Example: md=tres(md,'diagnostic');
+
+%check number of arguments
+
+if strcmpi(string,'diagnostic'),
+	if md.dim==2,
+		if isfield(md.results.DiagnosticSolution,'VxAverage'),
+			md.vx=PatchToVec(md.results.DiagnosticSolution.VxAverage);
+		else
+			md.vx=PatchToVec(md.results.DiagnosticSolution.Vx);
+		end
+		if isfield(md.results.DiagnosticSolution,'VyAverage'),
+			md.vy=PatchToVec(md.results.DiagnosticSolution.VyAverage);
+		else
+			md.vy=PatchToVec(md.results.DiagnosticSolution.Vy);
+		end
+	else 
+		md.vx=PatchToVec(md.results.DiagnosticSolution.Vx);
+		md.vy=PatchToVec(md.results.DiagnosticSolution.Vy);
+		if isfield(md.results.DiagnosticSolution,'Vz'),
+			md.vz=PatchToVec(md.results.DiagnosticSolution.Vz);
+		else
+			md.vz=zeros(md.numberofgrids,1);
+		end
+	end
+	md.vel=PatchToVec(md.results.DiagnosticSolution.Vel);
+
+	if isfield(md.results.DiagnosticSolution,'Pressure'),
+		md.pressure=PatchToVec(md.results.DiagnosticSolution.Pressure);
+	end
+	if md.numrifts,
+		if isfield(md.results.DiagnosticSolution,'riftproperties'),
+			md.riftproperties=md.results.DiagnosticSolution.riftproperties;
+		end
+	end
+	if md.control_analysis==1,
+		if (md.control_type==DragCoefficientEnum)
+			md.drag_coefficient=PatchToVec(md.results.DiagnosticSolution.(md.results.DiagnosticSolution.ControlType));
+		elseif (md.control_type==RheologyBbarEnum)
+			md.rheology_B=PatchToVec(md.results.DiagnosticSolution.(md.results.DiagnosticSolution.ControlType));
+		elseif (md.control_type==DhDtEnum)
+			md.dhdt=PatchToVec(md.results.DiagnosticSolution.(md.results.DiagnosticSolution.ControlType));
+		else
+			error('control type not implemented yet')
+		end
+	end
+elseif strcmpi(string,'dakota'),
+	md.dakotaresults=md.results.dakota;
+elseif strcmpi(string,'steadystate'),
+	md.vx=PatchToVec(md.results.SteadystateSolution.Vx);
+	md.vy=PatchToVec(md.results.SteadystateSolution.Vy);
+	if isfield(md.results.SteadystateSolution,'Vz'),
+		md.vz=PatchToVec(md.results.SteadystateSolution.Vz);
+	end
+
+	md.vel=PatchToVec(md.results.SteadystateSolution.Vel);
+	md.pressure=PatchToVec(md.results.SteadystateSolution.Pressure);
+	md.temperature=PatchToVec(md.results.SteadystateSolution.Temperature);
+	md.melting_rate=PatchToVec(md.results.SteadystateSolution.MeltingRate);
+elseif strcmpi(string,'thermal'),
+	md.temperature=PatchToVec(md.results.ThermalSolution.Temperature);
+	md.melting_rate=PatchToVec(md.results.ThermalSolution.MeltingRate);
+else 
+	error(['tres error message: analysis ' string ' not supported yet!']);
+end
Index: /issm/trunk/src/m/model/waitonlock.m
===================================================================
--- /issm/trunk/src/m/model/waitonlock.m	(revision 5901)
+++ /issm/trunk/src/m/model/waitonlock.m	(revision 5901)
@@ -0,0 +1,82 @@
+function flag=waitonlock(md,executionpath,login,port)
+%WAITONLOCK - wait for a file
+%
+%   This routine will return when a file named 'filename' is written to disk.
+%   If the time limit given in input is exceeded, return 0
+%
+%   Usage:
+%      flag=waitonlock(md,executionpath)
+
+%Get filename (lock file) and options
+filename=[executionpath '/' md.runtimename '/' md.name '.lock'];
+cluster=md.cluster;
+timelimit=md.waitonlock;
+
+%waitonlock will work if the lock is on the same machine only: 
+if ~strcmpi(oshostname(),cluster),
+
+	if port, 
+		%there is a tunnel, so we have a short at looking for the lock file.
+
+		disp(['waiting for ' filename ' hold on... (Ctrl+C to exit)'])
+		time=0; ispresent=0;
+		while (ispresent==0 & time<timelimit)
+			[status, result]=system(['ssh -q -p ' num2str(port) ' ' login '@localhost "if ( -e ' executionpath '/' md.runtimename '/' md.name '.lock ) echo 1"']);
+			if ~isempty(result),
+				if ismember('1',result),
+					ispresent=1;
+				else
+					ispresent=0;
+				end
+			else
+				ispresent=0;
+			end
+			pause(10); %tunnel can be unstable, let's not use it too much
+			time=time+1/60;
+		end
+		disp(['waitonlock: lock detected, with value of result:|' result '|']);
+		
+		%build output
+		if (time>timelimit),
+			disp('Time limit exceeded. Increase md.waitonlock');
+			disp('The results must be loaded manually with md=loadresultsfromcluster(md).');
+			error(['waitonlock error message: time limit exceeded']);
+			flag=0;
+		else
+			flag=1;
+		end
+	else
+		disp('solution launched on remote cluster. log in to detect job completion.');
+		choice=input('Is the job successfully completed? (y/n)','s');
+		if ~strcmp(choice,'y'), 
+			disp('Results not loaded... exiting'); 
+			flag=0;
+		else
+			flag=1;
+		end
+	end
+
+%job is running on the same machine
+else
+
+	%initialize time and file presence test flag
+	time=0; ispresent=0;
+	disp(['waiting for ' filename ' hold on... (Ctrl+C to exit)'])
+
+	%loop till file .lock exist or time is up
+	while (ispresent==0 & time<timelimit)
+		ispresent=exist(filename,'file');
+		pause(1);
+		time=time+1/60;
+	end
+
+	%build output
+	if (time>timelimit),
+		disp('Time limit exceeded. Increase md.waitonlock');
+		disp('The results must be loaded manually with md=loadresultsfromcluster(md).');
+		error(['waitonlock error message: time limit exceeded']);
+		flag=0;
+	else
+		flag=1;
+	end
+end
