Index: issm/trunk/configure.ac
===================================================================
--- issm/trunk/configure.ac	(revision 23389)
+++ issm/trunk/configure.ac	(revision 23394)
@@ -2,5 +2,5 @@
 
 #AUTOCONF
-AC_INIT([Ice Sheet System Model (ISSM)],[4.14],[issm@jpl.nasa.gov],[issm],[http://issm.jpl.nasa.gov]) #Initializing configure
+AC_INIT([Ice Sheet System Model (ISSM)],[4.15],[issm@jpl.nasa.gov],[issm],[http://issm.jpl.nasa.gov]) #Initializing configure
 AC_CONFIG_AUX_DIR([./aux-config])         #Put config files in aux-config
 AC_CONFIG_MACRO_DIR([m4])                 #m4 macros are located in m4
Index: issm/trunk/etc/environment.sh
===================================================================
--- issm/trunk/etc/environment.sh	(revision 23389)
+++ issm/trunk/etc/environment.sh	(revision 23394)
@@ -75,18 +75,10 @@
 fi
 
-#legacy mpich2 (To be removed)
-MPI_DIR="$ISSM_DIR/externalpackages/mpich2/install"
-if [ -d "$MPI_DIR" ]; then
-	export MPI_DIR
-	pathprepend   "$MPI_DIR/bin"
-	libpathappend "$MPI_DIR/lib"
-fi
-
 MPI_DIR="$ISSM_DIR/externalpackages/mpich/install"
 if [ -d "$MPI_DIR" ]; then
 	export MPI_DIR
 	export MPI_INC_DIR="$MPI_DIR/include"
-	pathprepend   "$MPI_DIR/bin"
-	libpathappend "$MPI_DIR/lib"
+	pathprepend    "$MPI_DIR/bin"
+	libpathprepend "$MPI_DIR/lib"
 fi
 
@@ -234,12 +226,4 @@
 pathprepend "$GMAKE_DIR/bin"
 
-PYTHON_DIR="$ISSM_DIR/externalpackages/python/install"
-if [ -d "$PYTHON_DIR" ]; then
-	export PYTHONPATH="$PYTHONPATH:$ISSM_DIR/lib"
-	pathprepend    "$PYTHON_DIR/bin"
-	libpathprepend "$PYTHON_DIR/lib"
-	libpathprepend "$ISSM_DIR/lib"
-fi
-
 MODELE_DIR="$ISSM_DIR/externalpackages/modelE/install"
 pathappend "$MODELE_DIR/src/exec"
Index: issm/trunk/examples/Pig2/DomainOutline.exp
===================================================================
--- issm/trunk/examples/Pig2/DomainOutline.exp	(revision 23394)
+++ issm/trunk/examples/Pig2/DomainOutline.exp	(revision 23394)
@@ -0,0 +1,101 @@
+## Name:
+## Icon:0
+# Points Count Value
+95 25000.000000
+# X pos Y pos
+-1712113.0179281300 -349656.0205056490
+-1711509.1917759699 -349354.1074295690
+-1709240.6586108401 -349354.1074295690
+-1707080.1508345299 -348922.0058743060
+-1705459.7700022999 -347193.5996532570
+-1703083.2114483600 -345249.1426545770
+-1701138.7544496800 -344168.8887664210
+-1698438.1197292900 -343952.8379887900
+-1698006.0181740201 -341900.3556012940
+-1693793.0280102200 -340279.9747690600
+-1691092.3932898301 -339631.8224361670
+-1688391.7585694401 -339415.7716585360
+-1686447.3015707601 -340063.9239914290
+-1683530.6160727399 -341036.1524907690
+-1682558.3875734000 -343304.6856558960
+-1682134.7209454600 -344182.1487658350
+-1682126.2860181299 -345681.2442098390
+-1681072.0444963200 -345932.4393879640
+-1680634.4718407800 -346682.5639403050
+-1680571.9614614199 -348557.8753211580
+-1677446.4424933300 -348370.3441830730
+-1675508.6207331200 -349495.5310115840
+-1676616.9911885399 -353567.0975933760
+-1672991.8601872099 -353799.6175753630
+-1668839.1631938200 -353999.1991486380
+-1667132.2298986400 -355121.4651541420
+-1666069.5534494901 -357496.8595698890
+-1662944.0344814099 -358309.4945015920
+-1660756.1712037399 -358747.0671571240
+-1657922.9836098100 -361682.8074238540
+-1656579.2228470000 -364003.8487410000
+-1653004.8841628900 -364748.0635758530
+-1653442.4568184200 -361622.5446077650
+-1651129.5727820301 -355684.0585683980
+-1648929.2928810001 -350845.9692010000
+-1646260.7698359799 -347802.2804785470
+-1644571.8968503401 -341785.6704672340
+-1643503.3064999001 -340869.0986596620
+-1643190.7546030900 -336680.9032424240
+-1642690.6715682000 -335243.1645171040
+-1641913.0916588283 -332341.0814454452
+-1640683.9739821283 -330436.6112348017
+-1637816.0327364956 -328532.1410241582
+-1635241.2508976001 -328652.8685499910
+-1631765.4107996500 -327017.1790921330
+-1625934.5618617306 -322342.6128395668
+-1620608.3852626982 -320438.1426289233
+-1616101.6204481323 -320438.1426289233
+-1611594.8556335662 -320914.2601815842
+-1607907.5026034669 -321866.4952869060
+-1602991.0318966676 -324723.2006028712
+-1599713.3847588014 -327579.9059188365
+-1593977.5022675355 -328532.1410241582
+-1590699.8551296694 -334721.6692087495
+-1589259.8391499999 -338300.0840570000
+-1588627.0898328500 -343572.9950327750
+-1588056.6000060199 -345432.3563530700
+-1586993.9235568701 -347432.6884926460
+-1589259.8391499999 -349315.9832070000
+-1585493.6744521901 -352996.1122558430
+-1585118.6121760199 -354496.3613605250
+-1585861.9157163899 -356240.3342513760
+-1586368.8197632500 -358747.0671571240
+-1587889.0972700799 -360996.6006787950
+-1586681.3716600600 -363935.4286441500
+-1585806.2263489999 -365748.2296456410
+-1586743.8820394201 -368373.6655788350
+-1586056.2678664399 -370123.9562009640
+-1585493.6744521901 -371124.1222707520
+-1586243.7990045301 -373562.0270658610
+-1414257.6683934701 -327460.5482541260
+-1412220.4351378100 -325972.8942023180
+-1404515.9240538401 -296165.1737279960
+-1387984.9332285200 -267002.0106682320
+-1360067.9373810000 -107884.1934940000
+-1423274.3497420000 -81217.9259650000
+-1402446.7987670000 -45916.9921070000
+-1478343.8065599999 60338.8188030000
+-1503760.4789370000 36334.1837800000
+-1528509.5619775900 63667.6809196406
+-1623055.4918765700 62841.1506965373
+-1725734.5897359999 -61372.6193030000
+-1719614.6457630000 -69022.5492690000
+-1759088.2843859999 -114004.1374660000
+-1755416.3180020000 -117064.1094530000
+-1761230.2647760001 -126856.0198080000
+-1758170.2927900001 -130527.9861920000
+-1762148.2563720001 -135423.9413700000
+-1764902.2311590000 -131445.9777880000
+-1769798.1863370000 -134199.9525750000
+-1775000.1387139999 -131445.9777880000
+-1794277.9622269999 -153477.7760890000
+-1712576.7101950001 -225081.1205660000
+-1729939.5891459100 -335652.4567604720
+-1712113.0179281300 -349656.0205056490
+
Index: issm/trunk/examples/Pig2/FrontRetreat.exp
===================================================================
--- issm/trunk/examples/Pig2/FrontRetreat.exp	(revision 23394)
+++ issm/trunk/examples/Pig2/FrontRetreat.exp	(revision 23394)
@@ -0,0 +1,17 @@
+## Name:FrontRetreat
+## Icon:0
+# Points Count Value
+11 1.000000
+# X pos Y pos
+-1626858.6376043619 -327176.4356578548
+-1605190.4936934854 -325911.1425827671
+-1604716.0087903275 -316263.2828852235
+-1607088.4333061168 -312625.5652943464
+-1612465.9288752396 -311676.5954880306
+-1618476.0709819060 -312467.4036599604
+-1624011.7281854146 -313890.8583694341
+-1626858.6376043619 -315788.7979820656
+-1627807.6074106777 -319268.3539385567
+-1628756.5772169936 -322589.7482606619
+-1626858.6376043619 -327176.4356578548
+
Index: issm/trunk/examples/Pig2/Pig.par
===================================================================
--- issm/trunk/examples/Pig2/Pig.par	(revision 23394)
+++ issm/trunk/examples/Pig2/Pig.par	(revision 23394)
@@ -0,0 +1,118 @@
+% Parameters to change/Try
+friction_coefficient = 10; % default [10]
+Temp_change          =  0;  % default [0 K]
+
+%Name and Coordinate system
+md.miscellaneous.name='PIG';
+md.mesh.epsg=3031;
+
+%NetCdf Loading
+disp('   Loading SeaRISE data from NetCDF');
+ncdata='../Data/Antarctica_5km_withshelves_v0.75.nc';
+x1    = ncread(ncdata,'x1');
+y1    = ncread(ncdata,'y1');
+usrf  = ncread(ncdata,'usrf')';
+topg  = ncread(ncdata,'topg')';
+temp  = ncread(ncdata,'presartm')';
+smb   = ncread(ncdata,'presprcp')';
+gflux = ncread(ncdata,'bheatflx_fox')';
+
+%Geometry
+disp('   Interpolating surface and ice base');
+md.geometry.base    = InterpFromGridToMesh(x1,y1,topg,md.mesh.x,md.mesh.y,0);
+md.geometry.surface = InterpFromGridToMesh(x1,y1,usrf,md.mesh.x,md.mesh.y,0);
+clear usrf, topg;
+
+disp('   Constructing thickness');
+md.geometry.thickness=md.geometry.surface-md.geometry.base;
+
+%ensure hydrostatic equilibrium on ice shelf: 
+di=md.materials.rho_ice/md.materials.rho_water;
+
+%Get the node numbers of floating nodes
+pos=find(md.mask.groundedice_levelset<0); 
+
+%apply a flotation criterion on the precedingly defined nodes and
+%redefine base and thickness accordingly
+md.geometry.thickness(pos)=1/(1-di)*md.geometry.surface(pos);
+md.geometry.base(pos)=md.geometry.surface(pos)-md.geometry.thickness(pos);
+md.geometry.hydrostatic_ratio=ones(md.mesh.numberofvertices,1); %For Dakota
+
+%Set min thickness to 1 meter
+pos0=find(md.geometry.thickness<=1);
+md.geometry.thickness(pos0)=1;
+md.geometry.surface=md.geometry.thickness+md.geometry.base;
+md.geometry.bed=md.geometry.base;
+md.geometry.bed(pos)=md.geometry.base(pos)-1000;
+
+%Initialization parameters
+disp('   Interpolating temperatures');
+md.initialization.temperature=InterpFromGridToMesh(x1,y1,temp,md.mesh.x,md.mesh.y,0)+273.15+Temp_change;
+clear temp;
+
+disp('   Loading velocities data from NetCDF');
+nsidc_vel='../Data/Antarctica_ice_velocity.nc';
+xmin    = ncreadatt(nsidc_vel,'/','xmin');
+ymax    = ncreadatt(nsidc_vel,'/','ymax');
+spacing = ncreadatt(nsidc_vel,'/','spacing');
+nx      = double(ncreadatt(nsidc_vel,'/','nx'));
+ny      = double(ncreadatt(nsidc_vel,'/','ny'));
+velx    = double(ncread(nsidc_vel,'vx'));
+vely    = double(ncread(nsidc_vel,'vy'));
+% Read coordinates
+xmin = strtrim(xmin);  
+xmin = str2num(xmin(1:end-2)); 
+ymax = strtrim(ymax);  
+ymax = str2num(ymax(1:end-2));  
+spacing = strtrim(spacing);
+spacing = str2num(spacing(1:end-2));  
+% Build the coordinates
+x2=xmin+(0:1:nx)'*spacing;
+y2=(ymax-ny*spacing)+(0:1:ny)'*spacing;
+
+disp('   Set observed velocities')
+md.initialization.vx=InterpFromGridToMesh(x2,y2,flipud(velx'),md.mesh.x,md.mesh.y,0);
+md.initialization.vy=InterpFromGridToMesh(x2,y2,flipud(vely'),md.mesh.x,md.mesh.y,0);
+md.initialization.vz=zeros(md.mesh.numberofvertices,1);
+md.initialization.vel=sqrt(md.initialization.vx.^2+md.initialization.vy.^2);
+clear velx vely;
+
+disp('   Set Pressure');
+md.initialization.pressure=md.materials.rho_ice*md.constants.g*md.geometry.thickness;
+
+disp('   Construct ice rheological properties');
+md.materials.rheology_n=3*ones(md.mesh.numberofelements,1);
+md.materials.rheology_B=paterson(md.initialization.temperature);
+
+%Forcings
+disp('   Interpolating surface mass balance');
+mass_balance=InterpFromGridToMesh(x1,y1,smb,md.mesh.x,md.mesh.y,0);
+md.smb.mass_balance=mass_balance*md.materials.rho_water/md.materials.rho_ice;
+clear smb;
+
+disp('   Set geothermal heat flux');
+md.basalforcings.geothermalflux=InterpFromGridToMesh(x1,y1,gflux,md.mesh.x,md.mesh.y,0);
+clear gflux;
+
+%Friction and inversion set up
+disp('   Construct basal friction parameters');
+md.friction.coefficient=friction_coefficient*ones(md.mesh.numberofvertices,1);
+md.friction.p=ones(md.mesh.numberofelements,1);
+md.friction.q=ones(md.mesh.numberofelements,1);
+
+%no friction applied on floating ice
+pos=find(md.mask.groundedice_levelset<0);
+md.friction.coefficient(pos)=0;
+md.groundingline.migration='SubelementMigration';
+
+md.inversion=m1qn3inversion();
+md.inversion.vx_obs=md.initialization.vx;
+md.inversion.vy_obs=md.initialization.vy;
+md.inversion.vel_obs=md.initialization.vel;
+
+disp('   Set boundary conditions');
+md=SetMarineIceSheetBC(md);
+md.basalforcings.floatingice_melting_rate = zeros(md.mesh.numberofvertices,1);
+md.basalforcings.groundedice_melting_rate = zeros(md.mesh.numberofvertices,1);
+md.thermal.spctemperature                 = md.initialization.temperature;
+md.masstransport.spcthickness             = NaN*ones(md.mesh.numberofvertices,1);
Index: issm/trunk/examples/Pig2/runme.m
===================================================================
--- issm/trunk/examples/Pig2/runme.m	(revision 23394)
+++ issm/trunk/examples/Pig2/runme.m	(revision 23394)
@@ -0,0 +1,231 @@
+steps=[1:8];
+
+if any(steps==1)   %Mesh Generation #1
+
+	%Mesh parameters
+	domain =['./DomainOutline.exp'];
+	hinit=5000;   % element size for the initial mesh
+	hmax=40000;    % maximum element size of the final mesh
+	hmin=4000;     % minimum element size of the final mesh
+	gradation=1.7; % maximum size ratio between two neighboring elements
+	err=8;         % maximum error between interpolated and control field
+
+	% Generate an initial uniform mesh (resolution = hinit m)
+	md=bamg(model,'domain',domain,'hmax',hinit);
+
+	% Get necessary data to build up the velocity grid
+	nsidc_vel='../Data/Antarctica_ice_velocity.nc'; 	
+	xmin    = strsplit(ncreadatt(nsidc_vel,'/','xmin'));      xmin    = str2num(xmin{2});
+	ymax    = strsplit(ncreadatt(nsidc_vel,'/','ymax'));      ymax    = str2num(ymax{2});
+	spacing = strsplit(ncreadatt(nsidc_vel,'/','spacing'));   spacing = str2num(spacing{2});
+	nx      = double(ncreadatt(nsidc_vel,'/','nx'));
+	ny      = double(ncreadatt(nsidc_vel,'/','ny'));
+	vx      = double(ncread(nsidc_vel,'vx'));
+	vy      = double(ncread(nsidc_vel,'vy'));
+
+	% Build the coordinates
+	x=xmin+(0:1:nx)'*spacing;
+	y=(ymax-ny*spacing)+(0:1:ny)'*spacing;
+	
+	% Interpolate velocities onto coarse mesh
+	vx_obs=InterpFromGridToMesh(x,y,flipud(vx'),md.mesh.x,md.mesh.y,0);
+	vy_obs=InterpFromGridToMesh(x,y,flipud(vy'),md.mesh.x,md.mesh.y,0);
+	vel_obs=sqrt(vx_obs.^2+vy_obs.^2);
+	clear vx vy x y;
+
+	% Adapt the mesh to minimize error in velocity interpolation
+	md=bamg(md,'hmax',hmax,'hmin',hmin,'gradation',gradation,'field',vel_obs,'err',err);
+
+	% Plot and save model
+	plotmodel(md,'data','mesh')
+	save ./Models/PIG_Mesh_generation md;
+end
+
+if any(steps==2)  %Masks #2
+
+	md = loadmodel('./Models/PIG_Mesh_generation');	
+
+	% Load SeaRISe dataset for Antarctica  http://websrv.cs.umt.edu/isis/index.php/Present_Day_Antarctica
+	searise='../Data/Antarctica_5km_withshelves_v0.75.nc';
+	
+	%read thickness mask from SeaRISE
+	x1=double(ncread(searise,'x1'));
+	y1=double(ncread(searise,'y1'));
+	thkmask=double(ncread(searise,'thkmask'));
+	
+	%interpolate onto our mesh vertices
+	groundedice=double(InterpFromGridToMesh(x1,y1,thkmask',md.mesh.x,md.mesh.y,0));
+	groundedice(groundedice<=0)=-1;
+	clear thkmask;
+
+	%fill in the md.mask structure
+	md.mask.groundedice_levelset=groundedice; %ice is grounded for mask equal one
+	md.mask.ice_levelset=-1*ones(md.mesh.numberofvertices,1);%ice is present when negatvie
+
+	plotmodel(md,'data',md.mask.groundedice_levelset,'title','grounded/floating','data',md.mask.ice_levelset,'title','ice/no-ice')
+	
+	save ./Models/PIG_SetMask md;
+end
+
+if any(steps==3)  %Parameterization #3
+
+	md = loadmodel('./Models/PIG_SetMask');
+	md = setflowequation(md,'SSA','all');
+	md = parameterize(md,'./Pig.par');
+	
+	save ./Models/PIG_Parameterization md;
+end
+
+if any(steps==4)  %Rheology B inversion
+
+	md = loadmodel('./Models/PIG_Parameterization');
+
+	% Control general
+	md.inversion.iscontrol=1;
+	md.inversion.maxsteps=40;
+	md.inversion.maxiter=40;
+	md.inversion.dxmin=0.1;
+	md.inversion.gttol=1.0e-6;
+	md.verbose=verbose('control',true);
+
+	% Cost functions
+	md.inversion.cost_functions=[101 103 502];
+	md.inversion.cost_functions_coefficients=ones(md.mesh.numberofvertices,3);
+	md.inversion.cost_functions_coefficients(:,1)=1000;
+	md.inversion.cost_functions_coefficients(:,2)=1;
+	md.inversion.cost_functions_coefficients(:,3)=1.e-16;
+
+	% Controls
+	md.inversion.control_parameters={'MaterialsRheologyBbar'};
+	md.inversion.min_parameters=md.materials.rheology_B;
+	md.inversion.max_parameters=md.materials.rheology_B;
+	pos = find(md.mask.groundedice_levelset<0);
+	md.inversion.min_parameters(pos) = cuffey(273);
+	md.inversion.max_parameters(pos) = cuffey(200);
+
+	% Additional parameters
+	md.stressbalance.restol=0.01;
+	md.stressbalance.reltol=0.1;
+	md.stressbalance.abstol=NaN;
+
+	% Solve
+	md.cluster=generic('name',oshostname,'np',2);
+	mds=extract(md,md.mask.groundedice_levelset<0);
+	mds=solve(mds,'Stressbalance');
+
+	% Update model rheology_B accordingly
+	md.materials.rheology_B(mds.mesh.extractedvertices)=mds.results.StressbalanceSolution.MaterialsRheologyBbar;
+	plotmodel(md,'data',md.materials.rheology_B)
+
+	% Save model
+	save ./Models/PIG_Control_B md;
+end
+
+if any(steps==5)  %drag inversion
+
+	md = loadmodel('./Models/PIG_Control_B');
+
+	% Cost functions
+	md.inversion.cost_functions=[101 103 501];
+	md.inversion.cost_functions_coefficients=ones(md.mesh.numberofvertices,3);
+	md.inversion.cost_functions_coefficients(:,1)=2000;
+	md.inversion.cost_functions_coefficients(:,2)=1;
+	md.inversion.cost_functions_coefficients(:,3)=8e-7;
+
+	% Controls
+	md.inversion.control_parameters={'FrictionCoefficient'};
+	md.inversion.min_parameters=1*ones(md.mesh.numberofvertices,1);
+	md.inversion.max_parameters=200*ones(md.mesh.numberofvertices,1);
+
+	% Solve
+	md=solve(md,'Stressbalance');
+
+	% Update model friction fields accordingly
+	md.friction.coefficient=md.results.StressbalanceSolution.FrictionCoefficient;
+
+	%Plot and save
+	plotmodel(md,...
+		'data',md.initialization.vel,'title','Observed velocity',...
+		'data',md.results.StressbalanceSolution.Vel,'title','Modeled Velocity',...
+		'data',md.geometry.base,'title','Bed elevation',...
+		'data',md.results.StressbalanceSolution.FrictionCoefficient,'title','Friction Coefficient',...
+		'colorbar#all','on','colorbartitle#1-2','(m/yr)',...
+		'caxis#1-2',([1.5,4000]),...
+		'colorbartitle#3','(m)', 'log#1-2',10);
+	save ./Models/PIG_Control_drag md;
+end
+
+if any(steps==6) %Transient Run #1
+
+	md = loadmodel('../Pig/Models/PIG_Control_drag');	
+
+	md.inversion.iscontrol=0;
+	md.transient.ismasstransport=1;
+	md.transient.isstressbalance=1;
+	md.transient.isgroundingline=1;
+	md.transient.ismovingfront=0;
+	md.transient.isthermal=0;
+	md.verbose.solution=1;
+	md.timestepping.time_step=0.1;
+	md.timestepping.final_time=10;
+	md.transient.requested_outputs={'default','IceVolume','IceVolumeAboveFloatation'};
+
+	%Set melt to 25 m/yr under floating ice
+	md.basalforcings.groundedice_melting_rate=zeros(md.mesh.numberofvertices,1);
+	md.basalforcings.floatingice_melting_rate=25*ones(md.mesh.numberofvertices,1);
+
+
+	md=solve(md,'Transient');
+	time      = cell2mat({md.results.TransientSolution(:).time});
+	V_control = cell2mat({md.results.TransientSolution(:).IceVolumeAboveFloatation});
+	plot(time,V_control); legend({'Control run'});
+
+	% Save model
+	save ./Models/PIG_Transient md;
+end
+
+if any(steps==7) %High Melt #2
+	md = loadmodel('./Models/PIG_Transient');	
+
+	%Set melt to 60 m/yr under floating ice
+	md.basalforcings.floatingice_melting_rate=60*ones(md.mesh.numberofvertices,1);
+
+	md=solve(md,'Transient');
+	V_melt = cell2mat({md.results.TransientSolution(:).IceVolumeAboveFloatation});
+	plot(time,[V_control',V_melt']); legend({'Control run','High melt'});
+
+	save ./Models/PIG_HighMelt md;
+end
+
+if any(steps==8) %Ice Front retreat
+	md = loadmodel('./Models/PIG_Transient');	
+
+	pos = find(ContourToNodes(md.mesh.x,md.mesh.y,'FrontRetreat.exp',2));
+	md.mask.ice_levelset(pos) = +1; %Deactivate nodes in retreated area
+
+	md=solve(md,'Transient');
+	V_retreat = cell2mat({md.results.TransientSolution(:).IceVolumeAboveFloatation});
+	plot(time,[V_control',V_melt',V_retreat']); legend({'Control run','High melt','Retreat'});
+
+	save ./Models/PIG_FrontRetreat md;
+end
+
+if any(steps==9) %High surface mass balance #3
+	%Load model from PIG_Transient
+	%...
+
+	%Change surface mass balance (x2)
+	%...
+
+	%Solve
+	%...
+
+	%Get volume time series
+	%...
+
+	%plot
+	plot(time,[V_control',V_melt',V_retreat',V_smb']); legend({'Control run','High melt','Retreat','SMB'});
+
+	%Save model
+	save ./Models/PIG_SMB md;
+end
Index: issm/trunk/externalpackages/README
===================================================================
--- issm/trunk/externalpackages/README	(revision 23389)
+++ 	(revision )
@@ -1,22 +1,0 @@
-To install all the ISSM libraries:
-
-1/ go into each library folder and type install.sh . 
-
-2/ There is no guarantee the compilation will work on all systems. A lot of tweaking of the 
-install.sh files will probably be involved. Especially, the configuration part of the install.
-
-Update: 
-now install.sh can call configure.sh for the most complex libraries, ie Petsc and Dakota. For those 
-libraries, go in the configs/ directory, pick up the correct configuration file and copy it to the top 
-folder of the library compilation. Tweak if necessary.
-
-machine characteristics:
-
--astrid: linux 64 bits
--castor: altix 64 bits
--cosmos: JPL cluster 32 bits
--macmathieu: iMac 24" 2009 32 bits
--macbookmathieu: MacBook Pro 13" 2010; OS X 10.6.7; 2.4GHz Intel Core 2 Duo 64 bits
--maceric: MacBook Pro 15" 2010 32 bits
--ogive: Mac Pro 2008 32 bits
--pleiades: AMES cluster
Index: issm/trunk/externalpackages/adjointmpi/install-pleiades.sh
===================================================================
--- issm/trunk/externalpackages/adjointmpi/install-pleiades.sh	(revision 23394)
+++ issm/trunk/externalpackages/adjointmpi/install-pleiades.sh	(revision 23394)
@@ -0,0 +1,25 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup
+rm -rf install src
+
+#Almost the same as adjoinable mpi but some adaptations to CoDiPack 
+svn co https://github.com/michel2323/AdjointMPI.git/branches/doubleFixMaster src
+mkdir install
+
+cd src
+autoreconf -fi
+ ./configure \
+	 --prefix="$ISSM_DIR/externalpackages/adjointmpi/install" \
+	 --with-mpi-root="/nasa/sgi/mpt/2.15r20/" \
+	 CXXFLAGS="-O2 -fPIC" CFLAGS="-O2 -fPIC" 
+
+#Compile adjoinablempi 
+make clean
+if [ $# -eq 0 ]; then
+	make 
+else
+	make -j $1
+fi
+make install
Index: issm/trunk/externalpackages/adjointmpi/install.sh
===================================================================
--- issm/trunk/externalpackages/adjointmpi/install.sh	(revision 23394)
+++ issm/trunk/externalpackages/adjointmpi/install.sh	(revision 23394)
@@ -0,0 +1,25 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup
+rm -rf install src
+
+#Almost the same as adjoinable mpi but some adaptations to CoDiPack 
+svn co https://github.com/michel2323/AdjointMPI.git/branches/doubleFixMaster src
+mkdir install
+
+cd src
+autoreconf -fi
+ ./configure \
+	 --prefix="$ISSM_DIR/externalpackages/adjointmpi/install" \
+	 --with-mpi-root="$ISSM_DIR/externalpackages/mpich/install" \
+	 CXXFLAGS="-O2 -fPIC" CFLAGS="-O2 -fPIC" 
+
+#Compile adjoinablempi 
+make clean
+if [ $# -eq 0 ]; then
+	make 
+else
+	make -j $1
+fi
+make install
Index: issm/trunk/externalpackages/codipack/install.sh
===================================================================
--- issm/trunk/externalpackages/codipack/install.sh	(revision 23394)
+++ issm/trunk/externalpackages/codipack/install.sh	(revision 23394)
@@ -0,0 +1,8 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup
+rm -rf install 
+
+#Download development version
+svn co https://github.com/SciCompKL/CoDiPack.git/trunk install
Index: issm/trunk/externalpackages/medipack/install.sh
===================================================================
--- issm/trunk/externalpackages/medipack/install.sh	(revision 23394)
+++ issm/trunk/externalpackages/medipack/install.sh	(revision 23394)
@@ -0,0 +1,8 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup
+rm -rf install 
+
+#Download development version
+svn co https://github.com/SciCompKL/MeDiPack/trunk install
Index: issm/trunk/externalpackages/petsc/install-3.9-macosx64.sh
===================================================================
--- issm/trunk/externalpackages/petsc/install-3.9-macosx64.sh	(revision 23394)
+++ issm/trunk/externalpackages/petsc/install-3.9-macosx64.sh	(revision 23394)
@@ -0,0 +1,34 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup
+rm -rf install petsc-3.9.3 src
+mkdir install src
+
+#Download from ISSM server
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/petsc-lite-3.9.3.tar.gz' 'petsc-3.9.3.tar.gz'
+
+#Untar and move petsc to install directory
+tar -zxvf  petsc-3.9.3.tar.gz
+mv petsc-3.9.3/* src/
+rm -rf petsc-3.9.3
+
+#configure
+cd src
+./config/configure.py \
+	--prefix="$ISSM_DIR/externalpackages/petsc/install" \
+	--with-mpi-dir="$ISSM_DIR/externalpackages/mpich/install" \
+	--PETSC_DIR="$ISSM_DIR/externalpackages/petsc/src" \
+	--with-debugging=1 \
+	--with-valgrind=0 \
+	--with-x=0 \
+	--with-ssl=0 \
+	--with-shared-libraries=1 \
+	--download-metis=1 \
+	--download-parmetis=1 \
+	--download-mumps=1 \
+	--download-scalapack=1
+
+#Compile and intall
+make
+make install
Index: issm/trunk/jenkins/jenkins.sh
===================================================================
--- issm/trunk/jenkins/jenkins.sh	(revision 23389)
+++ issm/trunk/jenkins/jenkins.sh	(revision 23394)
@@ -324,8 +324,8 @@
 #concatenate reports
 cd $ISSM_DIR/nightlylog/
-echo 'CHECKING NIGHTLYLOG DIRECTORY'
-echo '-----------------------------'
-ls -la
-echo '-----------------------------'
+#echo 'CHECKING NIGHTLYLOG DIRECTORY'
+#echo '-----------------------------'
+#ls -la
+#echo '-----------------------------'
 
 if [ -f matlab_log.log ]; then
Index: issm/trunk/jenkins/linux64_caladan_ad
===================================================================
--- issm/trunk/jenkins/linux64_caladan_ad	(revision 23389)
+++ issm/trunk/jenkins/linux64_caladan_ad	(revision 23394)
@@ -32,5 +32,4 @@
 					 mpich install-3.2-linux64.sh
 					 petsc install-3.7-linux64.sh
-					 metis install-5.0.1-linux64.sh
 					 triangle install-linux64.sh 
 					 gsl install-linux64.sh 
Index: issm/trunk/jenkins/linux64_caladan_ampi
===================================================================
--- issm/trunk/jenkins/linux64_caladan_ampi	(revision 23389)
+++ issm/trunk/jenkins/linux64_caladan_ampi	(revision 23394)
@@ -41,5 +41,4 @@
 					 mpich install-3.2-linux64.sh
 					 petsc install-3.7-linux64.sh
-					 metis install-5.0.1-linux64.sh
 					 triangle install-linux64.sh 
 					 gsl install-linux64.sh 
Index: issm/trunk/jenkins/linux64_ross_ad
===================================================================
--- issm/trunk/jenkins/linux64_ross_ad	(revision 23389)
+++ issm/trunk/jenkins/linux64_ross_ad	(revision 23394)
@@ -37,5 +37,4 @@
 					 mpich install-3.2-linux64.sh
 					 petsc install-3.7-linux64.sh
-					 metis install-5.0.1-linux64.sh
 					 triangle install-linux64.sh
 					 gsl install-linux64.sh
Index: issm/trunk/jenkins/linux64_ross_ampi
===================================================================
--- issm/trunk/jenkins/linux64_ross_ampi	(revision 23389)
+++ issm/trunk/jenkins/linux64_ross_ampi	(revision 23394)
@@ -44,5 +44,4 @@
 					 mpich install-3.2-linux64.sh
 					 petsc install-3.7-linux64.sh
-					 metis install-5.0.1-linux64.sh
 					 triangle install-linux64.sh
 					 gsl install-linux64.sh
Index: issm/trunk/jenkins/linux64_ross_codi
===================================================================
--- issm/trunk/jenkins/linux64_ross_codi	(revision 23394)
+++ issm/trunk/jenkins/linux64_ross_codi	(revision 23394)
@@ -0,0 +1,70 @@
+#
+#-------------------------------#
+# 1: ISSM general configuration #
+#-------------------------------#
+
+#MATLAB path
+MATLAB_PATH="/usr/local/MATLAB/R2015a"
+
+#ISSM CONFIGURATION
+ISSM_CONFIG='--prefix=$ISSM_DIR\
+				--without-kriging \
+				--without-kml \
+				--without-GiaIvins \
+				--without-Love \
+				--with-gsl-dir=$ISSM_DIR/externalpackages/gsl/install \
+				--with-matlab-dir=$MATLAB_PATH \
+				--with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
+				--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include  \
+				--with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib -lmpifort -lmpi" \
+				--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install/ \
+				--with-blas-lapack-dir=$ISSM_DIR/externalpackages/petsc/install \
+				--with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install/ \
+				--with-numthreads=4  \
+				--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
+				--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/4.9/ -lgfortran" \
+				--with-m1qn3-dir="$ISSM_DIR/externalpackages/m1qn3/install" \
+				--with-codipack-dir="$ISSM_DIR/externalpackages/codipack/install" \
+				--enable-tape-alloc \
+				--with-cxxoptflags="-DAD_TYPE=codi::RealReverse" \
+				--with-adjointmpi-dir="$ISSM_DIR/externalpackages/adjointmpi/install" \
+				--enable-development \
+				--enable-debugging '
+
+#PYTHON and MATLAB testing
+MATLAB_TEST=1
+PYTHON_TEST=0
+
+#-----------------------------------#
+# 3: External packages installation #
+#-----------------------------------#
+
+#List of external pakages to be installed and their installation scripts
+EXTERNALPACKAGES="autotools   install.sh
+                  cmake       install.sh
+                  mpich       install-3.2-linux64.sh
+                  petsc       install-3.7-linux64.sh
+                  triangle    install-linux64.sh
+                  gsl         install-linux64.sh
+                  m1qn3       install.sh
+                  adjointmpi  install.sh
+                  codipack    install.sh
+                  shell2junit install.sh"
+
+#-----------------#
+# 4: test options #
+#-----------------#
+
+#number of cpus used in ISSM installation and compilation (one is usually
+#safer as some packages are very sensitive to parallel compilation)
+NUMCPUS_INSTALL=5
+
+#number of cpus used in the nightly runs.
+NUMCPUS_RUN=1
+
+#Nightly run options. The matlab routine runme.m will be called
+#as follows: runme($MATLAB_NROPTIONS). The options must be understandable
+#by Matlab and runme.m
+#ex: "'id',[101 102 103]"
+MATLAB_NROPTIONS="'benchmark','all','id',[3015,3119,3480]"
+PYTHON_NROPTIONS="--benchmark='all' -i 3015 3119 3480"
Index: issm/trunk/jenkins/linux64_ross_dakota
===================================================================
--- issm/trunk/jenkins/linux64_ross_dakota	(revision 23389)
+++ issm/trunk/jenkins/linux64_ross_dakota	(revision 23394)
@@ -11,4 +11,6 @@
 	--disable-static \
 	--with-matlab-dir=$MATLAB_PATH \
+	--with-python-dir=/usr \
+	--with-python-numpy-dir=/home/jenkins/.local/lib/python2.7/site-packages/numpy \
 	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
 	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include  \
@@ -30,5 +32,5 @@
 #PYTHON and MATLAB testing
 MATLAB_TEST=1
-PYTHON_TEST=0
+PYTHON_TEST=1
 
 #-----------------------------------#
@@ -63,4 +65,4 @@
 #by Matlab and runme.m
 #ex: "'id',[101 102 103]"
-PYTHON_NROPTIONS="--exclude 243 701 702 435"
+PYTHON_NROPTIONS="--exclude 243 701 702 435 --include_name 'Dakota'"
 MATLAB_NROPTIONS="'exclude',[243,701,702,435]"
Index: issm/trunk/jenkins/linux64_ross_python
===================================================================
--- issm/trunk/jenkins/linux64_ross_python	(revision 23389)
+++ issm/trunk/jenkins/linux64_ross_python	(revision 23394)
@@ -10,9 +10,10 @@
 ISSM_CONFIG='--prefix=$ISSM_DIR \
 	--disable-static \
+	--with-matlab-dir=$MATLAB_PATH \
 	--with-python-dir=/usr \
 	--with-python-numpy-dir=/home/jenkins/.local/lib/python2.7/site-packages/numpy \
 	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
 	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include  \
-	--with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib -lmpi -lmpifort" \
+	--with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
 	--with-petsc-dir=$ISSM_DIR/externalpackages/petsc/install \
 	--with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
@@ -21,5 +22,5 @@
 	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/petsc/install \
 	--with-chaco-dir="$ISSM_DIR/externalpackages/chaco/install" \
-	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/4.9/ -lgfortran" \
+	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/4.9 -lgfortran" \
 	--with-m1qn3-dir=$ISSM_DIR/externalpackages/m1qn3/install \
 	--with-numthreads=4 \
@@ -50,8 +51,8 @@
 #number of cpus used in ISSM installation and compilation (one is usually
 #safer as some packages are very sensitive to parallel compilation)
-NUMCPUS_INSTALL=10
+NUMCPUS_INSTALL=5
 
 #number of cpus used in the nightly runs.
-NUMCPUS_RUN=5
+NUMCPUS_RUN=3
 
 #Nightly run options. The matlab routine runme.m will be called
Index: issm/trunk/jenkins/macosx_pine-island
===================================================================
--- issm/trunk/jenkins/macosx_pine-island	(revision 23389)
+++ issm/trunk/jenkins/macosx_pine-island	(revision 23394)
@@ -5,5 +5,5 @@
 
 #MATLAB path
-MATLAB_PATH="/Applications/MATLAB_R2015b.app/"
+MATLAB_PATH="/Applications/MATLAB_R2015b.app"
 
 #ISSM CONFIGURATION
@@ -48,5 +48,5 @@
 
 #number of cpus used in the nightly runs.
-NUMCPUS_RUN=2
+NUMCPUS_RUN=4
 
 #Nightly run options. The matlab routine runme.m will be called
Index: issm/trunk/jenkins/macosx_pine-island_dakota
===================================================================
--- issm/trunk/jenkins/macosx_pine-island_dakota	(revision 23389)
+++ issm/trunk/jenkins/macosx_pine-island_dakota	(revision 23394)
@@ -5,9 +5,11 @@
 
 #MATLAB path
-MATLAB_PATH="/Applications/MATLAB_R2015b.app/"
+MATLAB_PATH="/Applications/MATLAB_R2015b.app"
 
-#ISSM CONFIGURATION 
+#ISSM CONFIGURATION
 ISSM_CONFIG='--prefix=$ISSM_DIR \
 	--with-matlab-dir=$MATLAB_PATH \
+	--with-python-dir=/System/Library/Frameworks/Python.framework/Versions/2.7 \
+	--with-python-numpy-dir=/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy \
 	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
 	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include  \
@@ -27,5 +29,5 @@
 #PYTHON and MATLAB testing
 MATLAB_TEST=1
-PYTHON_TEST=0
+PYTHON_TEST=1
 
 #-----------------------------------#
@@ -54,10 +56,10 @@
 
 #number of cpus used in the nightly runs.
-NUMCPUS_RUN=2
+NUMCPUS_RUN=4
 
 #Nightly run options. The matlab routine runme.m will be called
 #as follows: runme($MATLAB_NROPTIONS). The options must be understandable
 #by Matlab and runme.m
-#ex: "'id',[101 102 103]"  ERRORS ARE LARGE FOR: 418 420 
-PYTHON_NROPTIONS=""
+#ex: "'id',[101 102 103]"  ERRORS ARE LARGE FOR: 418 420
+PYTHON_NROPTIONS="--exclude 119 243 514 701 702 703 234 235 418 420 --include_name 'Dakota'"
 MATLAB_NROPTIONS="'exclude',[119,243,514,701,702,703,234,235,418,420]"
Index: issm/trunk/jenkins/macosx_pine-island_dakota_static
===================================================================
--- issm/trunk/jenkins/macosx_pine-island_dakota_static	(revision 23389)
+++ issm/trunk/jenkins/macosx_pine-island_dakota_static	(revision 23394)
@@ -4,7 +4,7 @@
 
 #MATLAB path
-MATLAB_PATH="/Applications/MATLAB_R2015b.app/"
+MATLAB_PATH="/Applications/MATLAB_R2015b.app"
 
-#ISSM CONFIGURATION 
+#ISSM CONFIGURATION
 ISSM_CONFIG='--prefix=$ISSM_DIR \
 	--disable-static \
@@ -56,5 +56,5 @@
 
 #number of cpus used in the nightly runs.
-NUMCPUS_RUN=2
+NUMCPUS_RUN=4
 
 #Nightly run options. The matlab routine runme.m will be called
@@ -62,5 +62,5 @@
 #by Matlab and runme.m
 #ex: "'id',[101 102 103]"
-##                           bamg mesh   FS                     
+##                           bamg mesh   FS
 #PYTHON_NROPTIONS="--exclude_name 'Dakota'"
 #MATLAB_NROPTIONS="'exclude',[243,701,702,703,435,IdFromString('Dakota')]"
Index: issm/trunk/jenkins/macosx_pine-island_examples
===================================================================
--- issm/trunk/jenkins/macosx_pine-island_examples	(revision 23389)
+++ issm/trunk/jenkins/macosx_pine-island_examples	(revision 23394)
@@ -5,7 +5,7 @@
 
 #MATLAB path
-MATLAB_PATH="/Applications/MATLAB_R2015b.app/"
+MATLAB_PATH="/Applications/MATLAB_R2015b.app"
 
-#ISSM CONFIGURATION 
+#ISSM CONFIGURATION
 ISSM_CONFIG='--prefix=$ISSM_DIR \
 	--with-matlab-dir=$MATLAB_PATH \
Index: issm/trunk/m4/issm_options.m4
===================================================================
--- issm/trunk/m4/issm_options.m4	(revision 23389)
+++ issm/trunk/m4/issm_options.m4	(revision 23394)
@@ -9,5 +9,5 @@
 	dnl ISSM's internal options
 	dnl Build info{{{
-	
+
 	dnl build date
 	AC_PATH_PROGS(DATE, date)
@@ -153,5 +153,5 @@
 	AC_MSG_CHECKING(for wrappers compilation)
 	AM_CONDITIONAL([WRAPPERS], [test x$WRAPPERS_VALUE = xyes])
-	AC_MSG_RESULT($WRAPPERS_VALUE) 
+	AC_MSG_RESULT($WRAPPERS_VALUE)
 	dnl }}}
 	dnl Extensions{{{
@@ -251,5 +251,5 @@
 		fi
 	fi
-	AC_SUBST([OSLIBS]) 
+	AC_SUBST([OSLIBS])
 	AC_MSG_RESULT(done)
 	dnl }}}
@@ -281,21 +281,21 @@
 
 		AC_DEFINE([_HAVE_MATLAB_],[1],[with matlab in ISSM src])
-		
+
 		dnl 4. get MEXLIB MEXLINK and MEXEXT (experimental) except for windows
 		AC_MSG_CHECKING([matlab's mex compilation flags])
   		case "${host_os}" in
-  			*cygwin*) 
+  			*cygwin*)
   				if  test $VENDOR = intel-win7-32; then
-  					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib" 
+  					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib"
                MEXLINK="-Wl,/LIBPATH:`cygpath -m ${MATLAB_ROOT}/extern/lib/win32/microsoft` -Wl,/link -Wl,/EXPORT:mexFunction -Wl,/DLL"
 					MEXEXT=`$MATLAB_ROOT/bin/mexext.bat`
 					MEXEXT=".$MEXEXT"
   				elif test $VENDOR = intel-win7-64; then
-  					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib" 
-               MEXLINK="-Wl,/LIBPATH:`cygpath -m ${MATLAB_ROOT}/extern/lib/win64/microsoft` -Wl,/link -Wl,/EXPORT:mexFunction -Wl,/DLL" 
+  					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib"
+               MEXLINK="-Wl,/LIBPATH:`cygpath -m ${MATLAB_ROOT}/extern/lib/win64/microsoft` -Wl,/link -Wl,/EXPORT:mexFunction -Wl,/DLL"
 					MEXEXT=".mexw64"
   				elif test $VENDOR = MSVC-Win64 || test $VENDOR = MSVC-Win64-par; then
-  					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib" 
-               MEXLINK="-Wl,/link -Wl,/LIBPATH:`cygpath -m ${MATLAB_ROOT}/extern/lib/win64/microsoft` -Wl,/link -Wl,/EXPORT:mexFunction -Wl,/DLL" 
+  					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib"
+               MEXLINK="-Wl,/link -Wl,/LIBPATH:`cygpath -m ${MATLAB_ROOT}/extern/lib/win64/microsoft` -Wl,/link -Wl,/EXPORT:mexFunction -Wl,/DLL"
   					MATLABINCL="-I`cygpath -m $MATLAB_ROOT/extern/include/`"
 					MEXEXT=".mexw64"
@@ -311,5 +311,5 @@
 					 echo "#include <mex.h>" > conftest.cpp
 					 echo "void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]){}" >> conftest.cpp
-					 $MATLAB_ROOT/bin/mex -v -lmex conftest.cpp > conftest.tmp 2>&1 
+					 $MATLAB_ROOT/bin/mex -v -lmex conftest.cpp > conftest.tmp 2>&1
 					 rm -f conftest.cpp
 					 MEXLINK=$(cat conftest.tmp | grep LDFLAGS  | sed -e "s/LDFLAGS ://g")
@@ -333,5 +333,5 @@
 		MATLABWRAPPEREXT=$MEXEXT
 		AC_SUBST([MATLABWRAPPEREXT])
-	   AC_SUBST([MEXLIB]) 
+	   AC_SUBST([MEXLIB])
 		AC_SUBST([MEXLINK])
 	fi
@@ -345,5 +345,5 @@
 	AC_ARG_WITH([javascript],
 	  AS_HELP_STRING([--with-javascript], [compile javascript wrappers? default is no.]),
-	  [JAVASCRIPT=$withval],[JAVASCRIPT="no"]) 
+	  [JAVASCRIPT=$withval],[JAVASCRIPT="no"])
 
 	dnl Check whether javascript wrappers are desired
@@ -364,5 +364,5 @@
 	AC_ARG_WITH([triangle-dir],
 			  AS_HELP_STRING([--with-triangle-dir=DIR], [triangle root directory.]),
-			 [TRIANGLE_ROOT=$withval],[TRIANGLE_ROOT="no"]) 
+			 [TRIANGLE_ROOT=$withval],[TRIANGLE_ROOT="no"])
 
   dnl Check whether triangle is enabled
@@ -394,5 +394,5 @@
 				if test "x$HAVE_JAVASCRIPT" = "xyes"; then
 					dnl go to the bit code, not the library.
-					TRIANGLELIB=$TRIANGLE_ROOT/triangle.o 
+					TRIANGLELIB=$TRIANGLE_ROOT/triangle.o
 				else
 					TRIANGLELIB=$TRIANGLE_ROOT/triangle.a
@@ -402,5 +402,5 @@
 				if test "x$HAVE_JAVASCRIPT" = "xyes"; then
 					dnl go to the bit code, not the library.
-					TRIANGLELIB=$TRIANGLE_ROOT/triangle.o 
+					TRIANGLELIB=$TRIANGLE_ROOT/triangle.o
 				else
 					TRIANGLELIB=$TRIANGLE_ROOT/triangle.a
@@ -416,5 +416,5 @@
 	AC_ARG_WITH([boost-dir],
 	  AS_HELP_STRING([--with-boost-dir=DIR], [boost root directory.]),
-	  [BOOST_ROOT=$withval],[BOOST_ROOT="no"]) 
+	  [BOOST_ROOT=$withval],[BOOST_ROOT="no"])
 
 	dnl Check whether boost is enabled
@@ -443,6 +443,6 @@
 	AC_ARG_WITH([dakota-dir],
 	  AS_HELP_STRING([--with-dakota-dir=DIR], [dakota root directory.]),
-	  [DAKOTA_ROOT=$withval],[DAKOTA_ROOT="no"]) 
-	
+	  [DAKOTA_ROOT=$withval],[DAKOTA_ROOT="no"])
+
 	dnl Check whether dakota is enabled
 	AC_MSG_CHECKING([for dakota])
@@ -573,5 +573,5 @@
 	AC_ARG_WITH([python-dir],
 	  AS_HELP_STRING([--with-python-dir=DIR], [python root directory.]),
-	  [PYTHON_ROOT=$withval],[PYTHON_ROOT="no"]) 
+	  [PYTHON_ROOT=$withval],[PYTHON_ROOT="no"])
 
 	dnl Check whether python is enabled
@@ -592,10 +592,10 @@
 	if test "x$HAVE_PYTHON" = "xyes"; then
 		AC_MSG_CHECKING([for python version])
-		dnl Query Python for its version number.  Getting [:3] seems to be the
+		dnl Query Python for its version number. Getting [:3] seems to be the
 		dnl best way to do this; it's what "site.py" does in the standard library.
 		PYTHON_VERSION=$($PYTHON_ROOT/bin/python -c "import sys; print sys.version[[:3]]")
 		AC_MSG_RESULT($PYTHON_VERSION)
 
-		dnl recover major 
+		dnl recover major
 		PYTHON_MAJOR=${PYTHON_VERSION%.*}
 		AC_DEFINE_UNQUOTED([_PYTHON_MAJOR_],$PYTHON_MAJOR,[python version major])
@@ -643,6 +643,11 @@
 	AC_ARG_WITH([python-numpy-dir],
 	  AS_HELP_STRING([--with-python-numpy-dir=DIR], [python-numpy root directory.]),
-	  [PYTHON_NUMPY_ROOT=$withval],[PYTHON_NUMPY_ROOT="no"]) 
-	
+	  [PYTHON_NUMPY_ROOT=$withval],[PYTHON_NUMPY_ROOT="no"])
+
+	dnl you can find numpy by typing
+	dnl >>> import numpy
+	dnl >>> numpy.__file__
+	dnl '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/__init__.pyc'
+
 	dnl Check whether numpy is enabled
 	AC_MSG_CHECKING(for python-numpy)
@@ -667,6 +672,6 @@
 	AC_ARG_WITH([chaco-dir],
 	  AS_HELP_STRING([--with-chaco-dir=DIR], [chaco root directory.]),
-	  [CHACO_ROOT=$withval],[CHACO_ROOT="no"]) 
-	
+	  [CHACO_ROOT=$withval],[CHACO_ROOT="no"])
+
 	dnl Check whether chaco is enabled
 	AC_MSG_CHECKING([for chaco])
@@ -694,5 +699,5 @@
 	AC_ARG_WITH([scotch-dir],
 	  AS_HELP_STRING([--with-scotch-dir=DIR], [scotch root directory.]),
-	  [SCOTCH_ROOT=$withval],[SCOTCH_ROOT="no"]) 
+	  [SCOTCH_ROOT=$withval],[SCOTCH_ROOT="no"])
 
   dnl Check whether scotch is enabled
@@ -708,5 +713,5 @@
 	AC_MSG_RESULT($HAVE_SCOTCH)
 	AM_CONDITIONAL([SCOTCH],[test x$HAVE_SCOTCH = xyes])
-	
+
 	dnl scotch libraries
 	if test "x$HAVE_SCOTCH" = "xyes"; then
@@ -721,5 +726,5 @@
 	AC_ARG_WITH([esmf-dir],
 		AS_HELP_STRING([--with-esmf-dir=DIR], [esmf root directory.]),
-		[ESMF_ROOT=$withval],[ESMF_ROOT="no"]) 
+		[ESMF_ROOT=$withval],[ESMF_ROOT="no"])
 
 	dnl Check whether esmf is enabled
@@ -734,5 +739,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_ESMF)
-	
+
 	dnl esmf headers and libraries
 	if test "x$HAVE_ESMF" == "xyes"; then
@@ -745,8 +750,47 @@
 	AM_CONDITIONAL([ESMF], [test x$HAVE_ESMF = xyes])
 	dnl }}}
+	dnl codipack{{{
+	AC_ARG_WITH([codipack-dir],
+		AS_HELP_STRING([--with-codipack-dir=DIR], [CoDiPack root directory.]),
+		[CODIPACK_ROOT=$withval],[CODIPACK_ROOT="no"])
+
+	dnl Check whether codipack is enabled
+	AC_MSG_CHECKING([for CoDiPack])
+	if test "x$CODIPACK_ROOT" = "xno" ; then
+		HAVE_CODIPACK=no
+	else
+		HAVE_CODIPACK=yes
+		if ! test -d "$CODIPACK_ROOT"; then
+			AC_MSG_ERROR([codipack directory provided ($CODIPACK_ROOT) does not exist]);
+		fi
+	fi
+	AC_MSG_RESULT($HAVE_CODIPACK)
+
+	dnl codipack headers and libraries
+	if test "x$HAVE_CODIPACK" == "xyes"; then
+		CODIPACKINCL="-I$CODIPACK_ROOT/include"
+		AC_DEFINE([_HAVE_CODIPACK_],[1],[with codipack in ISSM src])
+		AC_DEFINE([_HAVE_AD_],[1],[with AD in ISSM src])
+		AC_SUBST([CODIPACKINCL])
+	fi
+	AM_CONDITIONAL([CODIPACK], [test x$HAVE_CODIPACK = xyes])
+   AM_COND_IF(CODIPACK,[CXXFLAGS+=" -std=c++11"])
+	dnl }}}
+	dnl tapeallocation {{{
+	AC_ARG_ENABLE([tape-alloc], dnl feature
+		AS_HELP_STRING([--enable-tape-alloc],[turn tape allocation support on]),
+		[enable_tape_alloc=$enableval], [enable_tape_alloc=no])
+
+	dnl check whether enabled
+	AC_MSG_CHECKING(for tape memory allocation)
+	if test "x$enable_tape_alloc" = xyes; then
+		AC_DEFINE([_AD_TAPE_ALLOC_],[1],[Macro to enable a priori tape allocation for AD])
+	fi
+	AC_MSG_RESULT($enable_tape_alloc)
+	dnl }}}
 	dnl adolc{{{
 	AC_ARG_WITH([adolc-dir],
 		AS_HELP_STRING([--with-adolc-dir=DIR], [adolc root directory.]),
-		[ADOLC_ROOT=$withval],[ADOLC_ROOT="no"]) 
+		[ADOLC_ROOT=$withval],[ADOLC_ROOT="no"])
 
 	dnl Check whether adolc is enabled
@@ -761,5 +805,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_ADOLC)
-	
+
 	dnl adolc headers and libraries
 	if test "x$HAVE_ADOLC" == "xyes"; then
@@ -773,11 +817,11 @@
 	fi
 	AM_CONDITIONAL([ADOLC], [test x$HAVE_ADOLC = xyes])
-        AM_COND_IF(ADOLC,[CXXFLAGS+=" -std=c++11"])
+   AM_COND_IF(ADOLC,[CXXFLAGS+=" -std=c++11"])
 	dnl }}}
 	dnl adolc-version{{{
 	AC_ARG_WITH([adolc-version],
 		AS_HELP_STRING([--with-adolc-version=number], [adolc version.]),
-		[ADOLC_VERSION=$withval],[ADOLC_VERSION=2]) 
-	AC_MSG_CHECKING(for adolc-version) 
+		[ADOLC_VERSION=$withval],[ADOLC_VERSION=2])
+	AC_MSG_CHECKING(for adolc-version)
 
 	AC_DEFINE_UNQUOTED([_ADOLC_VERSION_],$ADOLC_VERSION,[ADOLC version])
@@ -787,5 +831,5 @@
 	AC_ARG_WITH([adic2-dir],
 	  AS_HELP_STRING([--with-adic2-dir=DIR], [adic2 root directory.]),
-	  [ADIC2_ROOT=$withval],[ADIC2_ROOT="no"]) 
+	  [ADIC2_ROOT=$withval],[ADIC2_ROOT="no"])
 
 	dnl Check whether adic2 is enabled
@@ -815,5 +859,5 @@
 	  AS_HELP_STRING([--with-atlas-dir=DIR],[atlas root directory]),
 	  [ATLAS_ROOT=$withval],[ATLAS_ROOT="no"])
-			  
+
 	dnl Check whether atlas is enabled
 	AC_MSG_CHECKING(for atlas and cblas libraries)
@@ -836,8 +880,8 @@
 			;;
 			*linux*)
-			ATLASLIB=-L"$ATLAS_ROOT/lib -lcblas -latlas -lm " 
+			ATLASLIB=-L"$ATLAS_ROOT/lib -lcblas -latlas -lm "
 			;;
 			*darwin*)
-			ATLASLIB=-L"$ATLAS_ROOT/lib -lcblas -latlas -lm" 
+			ATLASLIB=-L"$ATLAS_ROOT/lib -lcblas -latlas -lm"
 			;;
 		esac
@@ -849,5 +893,5 @@
 	AC_ARG_WITH([gsl-dir],
 	  AS_HELP_STRING([--with-gsl-dir=DIR], [gsl root directory.]),
-	  [GSL_ROOT=$withval],[GSL_ROOT="no"]) 
+	  [GSL_ROOT=$withval],[GSL_ROOT="no"])
 
 	dnl Check whether gsl is enabled
@@ -862,5 +906,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_GSL)
-	
+
 	dnl gsl headers and libraries
 	if test "x$HAVE_GSL" == "xyes"; then
@@ -877,8 +921,8 @@
 	AM_CONDITIONAL([GSL], [test x$HAVE_GSL = xyes])
 	dnl }}}
-	dnl adjoinable-mpi{{{
+	dnl ampi (ADOLC){{{
 	AC_ARG_WITH([ampi-dir],
 	  AS_HELP_STRING([--with-ampi-dir=DIR], [adjoinable mpi root directory.]),
-	  [AMPI_ROOT=$withval],[AMPI_ROOT="no"]) 
+	  [AMPI_ROOT=$withval],[AMPI_ROOT="no"])
 
 	dnl Check whether ampi is enabled
@@ -893,5 +937,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_AMPI)
-	
+
 	dnl ampi headers and libraries
 	if test "x$HAVE_AMPI" == "xyes"; then
@@ -912,8 +956,73 @@
 	AM_CONDITIONAL([AMPI], [test x$HAVE_AMPI = xyes])
 	dnl }}}
+	dnl adjointmpi (CoDiPack){{{
+	AC_ARG_WITH([adjointmpi-dir],
+	  AS_HELP_STRING([--with-adjointmpi-dir=DIR], [adjoinable mpi root directory.]),
+	  [ADJOINTMPI_ROOT=$withval],[ADJOINTMPI_ROOT="no"])
+
+	dnl Check whether adjointmpi is enabled
+	AC_MSG_CHECKING([for adjointmpi])
+	if test "x$ADJOINTMPI_ROOT" = "xno" ; then
+		HAVE_ADJOINTMPI=no
+	else
+		HAVE_ADJOINTMPI=yes
+		if ! test -d "$ADJOINTMPI_ROOT"; then
+			AC_MSG_ERROR([adjointmpi directory provided ($ADJOINTMPI_ROOT) does not exist]);
+		fi
+	fi
+	AC_MSG_RESULT($HAVE_ADJOINTMPI)
+
+	dnl adjointmpi headers and libraries
+	if test "x$HAVE_ADJOINTMPI" == "xyes"; then
+		if test "x$CODIPACK_ROOT" == "xno"; then
+			AC_MSG_ERROR([cannot run adjoint mpi without CoDiPack]);
+		fi
+		ADJOINTMPIINCL="-I$ADJOINTMPI_ROOT/include"
+		ADJOINTMPILIB="-L$ADJOINTMPI_ROOT/lib  -lAMPI"
+		dnl Also set _HAVE_AMPI_, because the interface is (almost) the
+		dnl same as for adjoinable mpi...
+		AC_DEFINE([_HAVE_AMPI_],[1],[with adjoint mpi in ISSM src])
+		AC_DEFINE([_HAVE_ADJOINTMPI_],[1],[with adjoint mpi in ISSM src])
+		AC_SUBST([ADJOINTMPIINCL])
+		AC_SUBST([ADJOINTMPILIB])
+	fi
+	AM_CONDITIONAL([ADJOINTMPI], [test x$HAVE_ADJOINTMPI = xyes])
+	dnl }}}
+	dnl medipack (CoDiPack, ADOLC dev){{{
+	AC_ARG_WITH([medipack-dir],
+	  AS_HELP_STRING([--with-medipack-dir=DIR], [MeDiPack root directory.]),
+	  [MEDIPACK_ROOT=$withval],[MEDIPACK_ROOT="no"])
+
+	dnl Check whether medipack is enabled
+	AC_MSG_CHECKING([for medipack])
+	if test "x$MEDIPACK_ROOT" = "xno" ; then
+		HAVE_MEDIPACK=no
+	else
+		HAVE_MEDIPACK=yes
+		if ! test -d "$MEDIPACK_ROOT"; then
+			AC_MSG_ERROR([medipack directory provided ($MEDIPACK_ROOT) does not exist]);
+		fi
+	fi
+	AC_MSG_RESULT($HAVE_MEDIPACK)
+
+	dnl medipack headers and libraries
+	if test "x$HAVE_MEDIPACK" == "xyes"; then
+		if test "x$CODIPACK_ROOT" == "xno"; then
+			AC_MSG_ERROR([cannot run MeDiPack without CoDiPack]);
+		fi
+		MEDIPACKINCL="-I$MEDIPACK_ROOT/include -I$MEDIPACK_ROOT/src"
+		dnl Also set _HAVE_AMPI_, because the interface is (almost) the
+		dnl same as for adjoinable mpi...
+		AC_DEFINE([_HAVE_AMPI_],[1],[with adjoint mpi in ISSM src])
+		AC_DEFINE([_HAVE_MEDIPACK_],[1],[with MeDiPack in ISSM src])
+		AC_SUBST([MEDIPACKINCL])
+	fi
+	AM_CONDITIONAL([MEDIPACK], [test x$HAVE_MEDIPACK = xyes])
+
+	dnl }}}
 	dnl rose{{{
 	AC_ARG_WITH([rose-dir],
 	  AS_HELP_STRING([--with-rose-dir=DIR], [rose root directory.]),
-	  [ROSE_ROOT=$withval],[ROSE_ROOT="no"]) 
+	  [ROSE_ROOT=$withval],[ROSE_ROOT="no"])
 
 	dnl Check whether rose is enabled
@@ -941,5 +1050,5 @@
 	dnl mpi{{{
 	AC_MSG_CHECKING(for mpi)
-	
+
 	AC_ARG_WITH([mpi-include],
 	  AS_HELP_STRING([--with-mpi-include=DIR],[mpi include directory, necessary for parallel build]),
@@ -954,5 +1063,5 @@
 	  [MPI_LIBFLAGS=$withval],[MPI_LIBFLAGS=""])
 
-	
+
 	if test -z "$MPI_INCLUDE" ; then
 		HAVE_MPI=no
@@ -980,5 +1089,5 @@
 		if  test x$IS_WINDOWS = xyes; then
 			MPIINCL=/I"$MPI_INCLUDE"
-		else 
+		else
 			MPIINCL=-I"$MPI_INCLUDE"
 		fi
@@ -996,5 +1105,5 @@
 	  AS_HELP_STRING([--with-petsc-dir=DIR],[PETSc root directory, necessary for parallel build]),
 	  [PETSC_ROOT=$withval],[PETSC_ROOT="no"])
-		
+
 	dnl Check whether petsc is enabled
 	AC_MSG_CHECKING([for petsc])
@@ -1033,5 +1142,5 @@
 			AC_MSG_RESULT(no)
 		fi
-	
+
 		AC_ARG_WITH([petsc-arch],
 		  AS_HELP_STRING([--with-petsc-arch=DIR],[PETSc arch, necessary for PETSc < 3.0]),
@@ -1050,5 +1159,5 @@
 		 PETSCINCL+=" $PETSC_ROOT/include/$PETSC_ARCH"
 		fi
-		
+
 		case "${host_os}" in
 				*cygwin*)
@@ -1069,5 +1178,5 @@
 				if test "x$host_os_version" = "x3.0.101-0.31.1_1.0502.8394-cray_gem_s" ; then
 					PETSCLIB="-L$PETSC_ROOT/lib -lcraypetsc_gnu_real -lmetis"
-				fi 
+				fi
 				;;
 				*darwin*)
@@ -1122,8 +1231,8 @@
 
 			if test "$METIS_VERSION" = "4" ; then
-				METISINCL=-I"$METIS_ROOT/Lib" 
+				METISINCL=-I"$METIS_ROOT/Lib"
 				case "${host_os}" in
 					*cygwin*)
-					METISINCL="/I`cygpath -m $METIS_ROOT/Lib`" 
+					METISINCL="/I`cygpath -m $METIS_ROOT/Lib`"
 					METISLIB="-Wl,/link -Wl,/LIBPATH:`cygpath -m $METIS_ROOT` -Wl,libmetis.lib"
 					;;
@@ -1150,5 +1259,5 @@
 					;;
 				esac
-				METISINCL=-I"$METIS_ROOT/include" 
+				METISINCL=-I"$METIS_ROOT/include"
 				AC_DEFINE([_METIS_VERSION_],[5],[ Metis version number])
 			fi
@@ -1164,5 +1273,5 @@
 	AC_ARG_WITH([tao-dir],
 		AS_HELP_STRING([--with-tao-dir=DIR], [tao root directory.]),
-		[TAO_ROOT=$withval],[TAO_ROOT="no"]) 
+		[TAO_ROOT=$withval],[TAO_ROOT="no"])
 
 	dnl Check whether tao is enabled
@@ -1199,5 +1308,5 @@
 	AC_ARG_WITH([m1qn3-dir],
 		AS_HELP_STRING([--with-m1qn3-dir=DIR], [m1qn3 root directory.]),
-		[M1QN3_ROOT=$withval],[M1QN3_ROOT="no"]) 
+		[M1QN3_ROOT=$withval],[M1QN3_ROOT="no"])
 
 	dnl Check whether m1qn3 is enabled
@@ -1212,8 +1321,8 @@
 	fi
 	AC_MSG_RESULT($HAVE_M1QN3)
-	
+
 	dnl m1qn3 headers and libraries
 	if test "x$HAVE_M1QN3" == "xyes"; then
-	  M1QN3LIB="$M1QN3_ROOT/libm1qn3.a $M1QN3_ROOT//libddot.a"
+	  M1QN3LIB="$M1QN3_ROOT/libm1qn3.a $M1QN3_ROOT/libddot.a"
 	  AC_DEFINE([_HAVE_M1QN3_],[1],[with M1QN3 in ISSM src])
 	  AC_SUBST([M1QN3LIB])
@@ -1223,5 +1332,5 @@
 	AC_ARG_WITH([proj4-dir],
 		AS_HELP_STRING([--with-proj4-dir=DIR], [proj4 root directory.]),
-		[PROJ4_ROOT=$withval],[PROJ4_ROOT="no"]) 
+		[PROJ4_ROOT=$withval],[PROJ4_ROOT="no"])
 
 	dnl Check whether proj4 is enabled
@@ -1236,5 +1345,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_PROJ4)
-	
+
 	dnl proj4 headers and libraries
 	if test "x$HAVE_PROJ4" == "xyes"; then
@@ -1251,5 +1360,5 @@
 	  AS_HELP_STRING([--with-slepc-dir=DIR],[slepc root directory]),
 	  [SLEPC_ROOT=$withval],[SLEPC_ROOT="no"])
-			  
+
 	dnl Check whether slepc is enabled
 	AC_MSG_CHECKING([for slepc])
@@ -1263,5 +1372,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_SLEPC)
-	
+
 	dnl slepc headers and libraries
 	if test "x$HAVE_SLEPC" == "xyes"; then
@@ -1277,5 +1386,5 @@
 	  AS_HELP_STRING([--with-shapelib-dir=DIR], [shapelib root directory]),
 	  [SHAPELIB_ROOT=$withval],[SHAPELIB_ROOT="no"])
-			  
+
 	dnl Check whether shapelib is enabled
 	AC_MSG_CHECKING([for shapelib])
@@ -1289,5 +1398,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_SHAPELIB)
-	
+
 	dnl shapelib headers and libraries
 	if test "x$HAVE_SHAPELIB" == "xyes"; then
@@ -1309,5 +1418,5 @@
 	  AS_HELP_STRING([--with-scalapack-lib=LIBS],[scalapack libraries to include]),
 	  [SCALAPACKLIB=$withval],[SCALAPACKLIB="no"])
-			  
+
 	dnl Check whether scalapack is enabled
 	AC_MSG_CHECKING([for scalapack])
@@ -1329,5 +1438,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_SCALAPACK)
-	
+
 	dnl scalapack headers and libraries
 	if test "x$HAVE_SCALAPACK" = "xyes"; then
@@ -1340,5 +1449,5 @@
 	  AS_HELP_STRING([--with-blas-lapack-dir=DIR],[blas-lapack root directory]),
 	  [BLASLAPACK_ROOT=$withval],[BLASLAPACK_ROOT="no"])
-			  
+
 	dnl Check whether blas-lapack is enabled
 	AC_MSG_CHECKING([for blas-lapack])
@@ -1352,5 +1461,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_BLASLAPACK)
-	
+
 	dnl blas-lapack headers and libraries
 	if test "x$HAVE_BLASLAPACK" == "xyes"; then
@@ -1362,8 +1471,8 @@
 		  ;;
 		*linux*)
-		  BLASLAPACKLIB=-L"$BLASLAPACK_ROOT/lib -lflapack -lfblas " 
+		  BLASLAPACKLIB=-L"$BLASLAPACK_ROOT/lib -lflapack -lfblas "
 		  ;;
 		*darwin*)
-		  BLASLAPACKLIB=-L"$BLASLAPACK_ROOT/lib -lflapack -lfblas " 
+		  BLASLAPACKLIB=-L"$BLASLAPACK_ROOT/lib -lflapack -lfblas "
 		  ;;
 		esac
@@ -1393,17 +1502,17 @@
 	dnl plapack{{{
 	AC_MSG_CHECKING(for plapack)
-	
+
 	AC_ARG_WITH([plapack-lib],
 	  AS_HELP_STRING([--with-plapack-lib = lib],[plapack library]),
 	  [PLAPACK_LIB=$withval],[PLAPACK_LIB=""])
-	
+
 	AC_ARG_WITH([plapack-include],
 			  AS_HELP_STRING([--with-plapack-include = include],
 							 [plapack include ]),
 			  [PLAPACK_INCLUDE=$withval],[PLAPACK_INCLUDE=""])
-	  
+
 	if test -n "$PLAPACK_LIB"; then
 		if test -n "$PLAPACK_INCLUDE"; then
-		
+
 			HAVE_PLAPACK=yes
 			PLAPACKINCL="$PLAPACK_INCLUDE"
@@ -1424,5 +1533,5 @@
 	  AS_HELP_STRING([--with-mumps-dir=DIR],[mumps root directory]),
 	  [MUMPS_ROOT=$withval],[MUMPS_ROOT="no"])
-			  
+
 	dnl Check whether mumps is enabled
 	AC_MSG_CHECKING([for mumps])
@@ -1436,5 +1545,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_MUMPS)
-	
+
 	dnl mumps headers and libraries
 	if test "x$HAVE_MUMPS" == "xyes"; then
@@ -1455,5 +1564,5 @@
 	if test "x$HAVE_MUMPS" != "xyes"; then
 	AC_MSG_CHECKING(for mumps2 (stand alone))
-	
+
 	AC_ARG_WITH([mumps2-include],
 	  AS_HELP_STRING([--with-mumps2-include=DIR],[mumps2 include directory, necessary for parallel build]),
@@ -1464,5 +1573,5 @@
 	  [MUMPS_LIBFLAGS=$withval],[MUMPS_LIBFLAGS=""])
 
-	
+
 	if test -z "$MUMPS_INCLUDE" ; then
 		HAVE_MUMPS=no
@@ -1490,5 +1599,5 @@
 		AS_HELP_STRING([--with-blacs-dir=DIR],[blacs root directory]),
 			  [BLACS_ROOT=$withval],[BLACS_ROOT="no"])
-			  
+
 	dnl Check whether blacs is enabled
 	AC_MSG_CHECKING([for blacs])
@@ -1502,5 +1611,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_BLACS)
-	
+
 	dnl blacs headers and libraries
 	if test "x$HAVE_BLACS" == "xyes"; then
@@ -1516,5 +1625,5 @@
 	  AS_HELP_STRING([--with-hypre-dir=DIR],[hypre root directory]),
 			  [HYPRE_ROOT=$withval],[HYPRE_ROOT="no"])
-			  
+
 	dnl Check whether hypre is enabled
 	AC_MSG_CHECKING([for hypre])
@@ -1590,5 +1699,5 @@
 		fi
 	  dnl }}}
-dnl superlu{{{ 
+dnl superlu{{{
 	AC_ARG_WITH([superlu-dir],
 				AS_HELP_STRING([--with-superlu-dir=DIR],[superlu root directory]),
@@ -1606,5 +1715,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_SUPERLU)
-	
+
 	dnl superlu headers and libraries
 	if test "x$HAVE_SUPERLU" == "xyes"; then
@@ -1616,5 +1725,5 @@
 	 fi
 	 dnl }}}
-dnl spooles{{{ 
+dnl spooles{{{
 	AC_ARG_WITH([spooles-dir],
 				AS_HELP_STRING([--with-spooles-dir=DIR],[spooles root directory]),
@@ -1632,5 +1741,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_SPOOLES)
-	
+
 	dnl spooles headers and libraries
 	if test "x$HAVE_SPOOLES" == "xyes"; then
@@ -1642,5 +1751,5 @@
 	 fi
 	 dnl }}}
-dnl pastix{{{ 
+dnl pastix{{{
 	AC_ARG_WITH([pastix-dir],
 				AS_HELP_STRING([--with-pastix-dir=DIR],[pastix root directory]),
@@ -1658,5 +1767,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_PASTIX)
-	
+
 	dnl pastix headers and libraries
 	if test "x$HAVE_PASTIX" == "xyes"; then
@@ -1672,5 +1781,5 @@
 	  AS_HELP_STRING([--with-ml-dir=DIR],[ml root directory]),
 			  [ML_ROOT=$withval],[ML_ROOT="no"])
-			  
+
 	dnl Check whether ml is enabled
 	AC_MSG_CHECKING([for ml])
@@ -1684,5 +1793,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_ML)
-	
+
 	dnl ml headers and libraries
 	if test "x$HAVE_ML" == "xyes"; then
@@ -1698,5 +1807,5 @@
 		  AS_HELP_STRING([--with-umfpack-dir=DIR],[UMFPACK root directory]),
 					[UMFPACK_ROOT=$withval],[UMFPACK_ROOT="no"])
-			  
+
 	dnl Check whether umfpack is enabled
 	AC_MSG_CHECKING([for umfpack])
@@ -1710,5 +1819,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_UMFPACK)
-	
+
 	dnl umfpack headers and libraries
 	if test "x$HAVE_UMFPACK" == "xyes"; then
@@ -1738,6 +1847,6 @@
 		AC_ARG_WITH([math77-dir],
 					AS_HELP_STRING([--with-math77-dir=DIR], [math77 root directory.]),
-					[MATH77_ROOT=$withval],[MATH77_ROOT="no"]) 
-		  
+					[MATH77_ROOT=$withval],[MATH77_ROOT="no"])
+
 	dnl Check whether math77 is enabled
 	AC_MSG_CHECKING([for math77])
@@ -1751,5 +1860,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_MATH77)
-	
+
 	dnl math77 headers and libraries
 	if test "x$HAVE_MATH77" == "xyes"; then
@@ -1762,5 +1871,5 @@
 	AC_ARG_WITH([fortran],
 		AS_HELP_STRING([--with-fortran = YES], [do we compile fortran code (default is yes)]),
-		[FORTRAN=$withval],[FORTRAN=yes]) 
+		[FORTRAN=$withval],[FORTRAN=yes])
 	AC_MSG_CHECKING(for fortran compilation)
 	if test "x$FORTRAN" = "xyes"; then
@@ -1830,5 +1939,5 @@
 	AC_ARG_WITH([meteoio-dir],
 	  AS_HELP_STRING([--with-meteoio-dir=DIR], [use meteoio in conjunction with snowpack model.]),
-	  [METEOIO_ROOT=$withval],[METEOIO_ROOT="no"]) 
+	  [METEOIO_ROOT=$withval],[METEOIO_ROOT="no"])
 
 	dnl Check whether meteoio is enabled
@@ -1843,5 +1952,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_METEOIO)
-	
+
 	dnl meteoio headers and libraries
 	if test "x$HAVE_METEOIO" == "xyes"; then
@@ -1858,5 +1967,5 @@
 	AC_ARG_WITH([snowpack-dir],
 	  AS_HELP_STRING([--with-snowpack-dir=DIR], [use snowpack for surface mass balance model.]),
-	  [SNOWPACK_ROOT=$withval],[SNOWPACK_ROOT="no"]) 
+	  [SNOWPACK_ROOT=$withval],[SNOWPACK_ROOT="no"])
 
 	dnl Check whether snowpack is enabled
@@ -1871,5 +1980,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_SNOWPACK)
-	
+
 	dnl snowpack headers and libraries
 	if test "x$HAVE_SNOWPACK" == "xyes"; then
@@ -1886,5 +1995,5 @@
 	AC_ARG_WITH([neopz-dir],
 		AS_HELP_STRING([--with-neopz-dir=DIR], [neopz root directory.]),
-		[NEOPZ_ROOT=$withval],[NEOPZ_ROOT="no"]) 
+		[NEOPZ_ROOT=$withval],[NEOPZ_ROOT="no"])
 
 	dnl Check whether neopz is enabled
@@ -1899,5 +2008,5 @@
 	fi
 	AC_MSG_RESULT($HAVE_NEOPZ)
-	
+
 	dnl neopz headers and libraries
 	if test "x$HAVE_NEOPZ" == "xyes"; then
@@ -1938,5 +2047,5 @@
 	AC_ARG_WITH([bamg],
 		AS_HELP_STRING([--with-bamg = YES],[compile with bamg capabilities (default is yes)]),
-		[BAMG=$withval],[BAMG=yes]) 
+		[BAMG=$withval],[BAMG=yes])
 	AC_MSG_CHECKING(for bamg capability compilation)
 
@@ -1952,5 +2061,5 @@
 	AC_ARG_WITH([ocean],
 		AS_HELP_STRING([--with-ocean = YES],[compile with ice/ocean coupling (default is no)]),
-		[OCEAN=$withval],[OCEAN=no]) 
+		[OCEAN=$withval],[OCEAN=no])
 	AC_MSG_CHECKING(for ice/ocean capability compilation)
 
@@ -1966,5 +2075,5 @@
 	AC_ARG_WITH([kml],
 		AS_HELP_STRING([--with-kml = YES],[compile with kml capabilities (default is no)]),
-		[KML=$withval],[KML=no]) 
+		[KML=$withval],[KML=no])
 	AC_MSG_CHECKING(for kml capability compilation)
 
@@ -1980,5 +2089,5 @@
 	AC_ARG_WITH([kriging],
 		AS_HELP_STRING([--with-kriging = YES],[compile with kriging capabilities (default is yes)]),
-		[KRIGING=$withval],[KRIGING=yes]) 
+		[KRIGING=$withval],[KRIGING=yes])
 	AC_MSG_CHECKING(for kriging capability compilation)
 
@@ -1997,5 +2106,5 @@
 	AC_ARG_WITH([ios],
 		AS_HELP_STRING([--with-ios = YES], [compile with iOS capabilities (default is no, alternatives are yes)]),
-		[IOS=$withval],[IOS=no]) 
+		[IOS=$withval],[IOS=no])
 	AC_MSG_CHECKING(for iOS compilation)
 
@@ -2016,5 +2125,5 @@
 	AC_ARG_WITH([android],
 		AS_HELP_STRING([--with-android = EXE], [compile with android capabilities (default is no, alternatives are exe and jni)]),
-		[ANDROID=$withval],[ANDROID=no]) 
+		[ANDROID=$withval],[ANDROID=no])
 	AC_MSG_CHECKING(for android capability compilation)
 
@@ -2043,7 +2152,7 @@
 	AC_ARG_WITH([android-ndk],
 	  AS_HELP_STRING([--with-android-ndk=DIR], [android-ndk root directory.]),
-	  [ANDROID_NDK_ROOT=$withval],[ANDROID_NDK_ROOT=""]) 
+	  [ANDROID_NDK_ROOT=$withval],[ANDROID_NDK_ROOT=""])
 	AC_MSG_CHECKING(with android ndk)
-	
+
 	if test -d "$ANDROID_NDK_ROOT"; then
 		dnl defaults
@@ -2061,8 +2170,8 @@
 	dnl other options
 	dnl optimization{{{
-	dnl bypass standard optimization -g -O2 ? 
+	dnl bypass standard optimization -g -O2 ?
 	AC_ARG_WITH([cxxoptflags],
 	  AS_HELP_STRING([--with-cxxoptflags = CXXOPTFLAGS], [optimization using CXX flags, ex: --with-cxxoptflags=-march=opteron -O3]),
-	  [CXXOPTFLAGS=$withval],[CXXOPTFLAGS="-g -O2 -fPIC"]) 
+	  [CXXOPTFLAGS=$withval],[CXXOPTFLAGS="-g -O2 -fPIC"])
 	AC_MSG_CHECKING(for c++ optimization flags)
 	AC_SUBST([CXXOPTFLAGS])
@@ -2079,5 +2188,5 @@
 	MULTITHREADINLIB=""
 	if test "$NUMTHREADS_VALUE" != "1"; then
-		
+
 		MULTITHREADINGLIB="-lpthread -lrt"
 		case "${host_os}" in
@@ -2094,12 +2203,19 @@
 		AC_DEFINE([_MULTITHREADING_],[1],[with numthreads enabled])
 	fi
+	dnl check that it is an integer
+	if [[ "$NUMTHREADS_VALUE" -eq   "$NUMTHREADS_VALUE" 2> /dev/null ]] ; then
+	 dnl cool we have an integer
+	 :
+	else
+	 AC_MSG_ERROR([Number of threads provided ($NUMTHREADS_VALUE) is not an integer]);
+	fi
 	AC_DEFINE_UNQUOTED([_NUMTHREADS_],[$NUMTHREADS_VALUE],[number of threads])
 	AC_SUBST([MULTITHREADINGLIB])
-	AC_MSG_RESULT($NUMTHREADS_VALUE) 
+	AC_MSG_RESULT($NUMTHREADS_VALUE)
 	dnl }}}
 	dnl 64bit {{{
 	AC_ARG_WITH([64bit-indices],
 	  AS_HELP_STRING([--with-64bit-indices = bool], [use 64 bit integers, default 0, ex: --with-64bit-indices=1]),
-	  [USE_64BIT_INDICES=$withval],[USE_64BIT_INDICES=0]) 
+	  [USE_64BIT_INDICES=$withval],[USE_64BIT_INDICES=0])
 	AC_MSG_CHECKING(for 64 bit indices)
 
@@ -2132,5 +2248,5 @@
 			  AC_MSG_ERROR([need fortran compiler to compile GiaIvins (or use --without-GiaIvins )]);
 		 fi
-			
+
        dnl check that fortran is provided if Love is on
 		 if test "$HAVE_LOVE" = "yes" &&  test "$HAVE_FORTRAN" = "no" ; then
@@ -2142,5 +2258,5 @@
 				AC_MSG_ERROR([need mpi if using the metis partitioner!]);
 		  fi
-		
+
 		dnl check that if we run adolc, we don't compile krigging.exe
 		if test "$HAVE_ADOLC" = "yes"  && test "$HAVE_KRIGING" = "yes" ; then
@@ -2151,4 +2267,10 @@
 			AC_MSG_ERROR([cannot compile ISSM with both PETSc and adolc]);
 		fi
+		if test "$HAVE_ADOLC" = "yes"  && test "$HAVE_CODIPACK" = "yes" ; then
+			AC_MSG_ERROR([cannot compile ISSM with both ADOLC and CoDiPack]);
+		fi
+		if test "$HAVE_ADJOINTMPI" = "yes"  && test "$HAVE_MEDIPACK" = "yes" ; then
+			AC_MSG_ERROR([cannot compile ISSM with both MeDiPack and AdjointMPI]);
+		fi
 		dnl check that if we run meteoio, we have snowpack also
 		if test "$HAVE_METEOIO" = "yes"  && test "$HAVE_SNOWPACK" = "no" ; then
Index: issm/trunk/src/c/Makefile.am
===================================================================
--- issm/trunk/src/c/Makefile.am	(revision 23389)
+++ issm/trunk/src/c/Makefile.am	(revision 23394)
@@ -1,3 +1,3 @@
-AM_CPPFLAGS = @NEOPZINCL@ @DAKOTAINCL@ @SHAPELIBINCL@ @PETSCINCL@ @SLEPCINCL@ @AMPIINCL@ @MPIINCL@ @METISINCL@ @CHACOINCL@ @SCOTCHINCL@ @PLAPACKINCL@ @BLASLAPACKINCL@ @MKLINCL@ @MUMPSINCL@ @TRIANGLEINCL@ @SPAIINCL@ @HYPREINCL@ @PROMETHEUSINCL@ @SUPERLUINCL@ @SPOOLESINCL@ @PASTIXINCL@ @MLINCL@ @TAOINCL@ @ADIC2INCL@ @ADOLCINCL@ @GSLINCL@ @BOOSTINCL@ @ANDROID_NDKINCL@ @METEOIOINCL@ @SNOWPACKINCL@ @PROJ4INCL@
+AM_CPPFLAGS = @NEOPZINCL@ @DAKOTAINCL@ @SHAPELIBINCL@ @PETSCINCL@ @SLEPCINCL@ @AMPIINCL@ @ADJOINTMPIINCL@ @MEDIPACKINCL@ @MPIINCL@ @METISINCL@ @CHACOINCL@ @SCOTCHINCL@ @PLAPACKINCL@ @BLASLAPACKINCL@ @MKLINCL@ @MUMPSINCL@ @TRIANGLEINCL@ @SPAIINCL@ @HYPREINCL@ @PROMETHEUSINCL@ @SUPERLUINCL@ @SPOOLESINCL@ @PASTIXINCL@ @MLINCL@ @TAOINCL@ @ADIC2INCL@ @ADOLCINCL@ @CODIPACKINCL@ @GSLINCL@ @BOOSTINCL@ @ANDROID_NDKINCL@ @METEOIOINCL@ @SNOWPACKINCL@ @PROJ4INCL@
 
 AUTOMAKE_OPTIONS = subdir-objects
@@ -51,8 +51,11 @@
 					 ./modules/BamgTriangulatex/BamgTriangulatex.cpp
 
-#do not include AmrBamg with ADOLC
+#do not include AmrBamg with AD
 if ADOLC
 else
+if CODIPACK
+else
 issm_sources += ./classes/AmrBamg.cpp
+endif
 endif
 endif
@@ -172,4 +175,5 @@
 					./shared/Elements/PrintArrays.cpp\
 					./shared/Elements/PddSurfaceMassBalance.cpp\
+					./shared/Elements/PddSurfaceMassBalanceSicopolis.cpp\
 					./shared/Elements/ComputeDelta18oTemperaturePrecipitation.cpp\
 					./shared/Elements/ComputeMungsmTemperaturePrecipitation.cpp\
@@ -320,4 +324,12 @@
 					./classes/Inputs/TetraInput.cpp
 #}}}
+#ADJOINTMPI/MeDiPack sources {{{
+if ADJOINTMPI
+issm_sources += ./toolkits/codipack/ampi_interface.cpp
+endif
+if MEDIPACK
+issm_sources += ./toolkits/codipack/ampi_interface.cpp
+endif
+# }}}
 #DAKOTA sources  {{{
 if DAKOTA
@@ -632,5 +644,5 @@
 if !WINDOWS
 if !STANDALONE_LIBRARIES
-libISSMCore_la_LIBADD = $(PETSCLIB) $(TAOLIB) $(M1QN3LIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB) $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB)   $(ADOLCLIB) $(AMPILIB) $(METEOIOLIB) $(SNOWPACKLIB)
+libISSMCore_la_LIBADD = $(PETSCLIB) $(TAOLIB) $(M1QN3LIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB) $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB)   $(ADOLCLIB) $(AMPILIB) $(ADJOINTMPILIB) $(METEOIOLIB) $(SNOWPACKLIB)
 if FORTRAN
 libISSMCore_la_LIBADD += $(FLIBS) $(FORTRANLIB)
@@ -714,5 +726,5 @@
 
 #External packages
-LDADD +=  $(NEOPZLIB) $(TAOLIB) $(M1QN3LIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(PETSCLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB)  $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB) $(AMPILIB) $(ADOLCLIB) $(MPILIB) $(METEOIOLIB) $(SNOWPACKLIB) $(PROJ4LIB)
+LDADD +=  $(NEOPZLIB) $(TAOLIB) $(M1QN3LIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(PETSCLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB)  $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB) $(AMPILIB) $(ADJOINTMPILIB) $(ADOLCLIB) $(MPILIB) $(METEOIOLIB) $(SNOWPACKLIB) $(PROJ4LIB)
 
 if FORTRAN
Index: issm/trunk/src/c/analyses/EnthalpyAnalysis.cpp
===================================================================
--- issm/trunk/src/c/analyses/EnthalpyAnalysis.cpp	(revision 23389)
+++ issm/trunk/src/c/analyses/EnthalpyAnalysis.cpp	(revision 23394)
@@ -43,6 +43,7 @@
 		int smb_model;
 		iomodel->FindConstant(&smb_model,"md.smb.model");
-		if(smb_model==SMBpddEnum)     isdynamic=true;
-		if(smb_model==SMBd18opddEnum) isdynamic=true;
+		if(smb_model==SMBpddEnum)				isdynamic=true;
+		if(smb_model==SMBd18opddEnum)			isdynamic=true;
+		if(smb_model==SMBpddSicopolisEnum)	isdynamic=true;
 	}
 
@@ -1200,4 +1201,6 @@
 		_assert_((Hc+Ht)>0.);
 		lambda = Hc/(Hc+Ht);
+		_assert_(lambda>=0.);
+		_assert_(lambda<=1.);
 		kappa  = kappa_c*kappa_t/(lambda*kappa_t+(1.-lambda)*kappa_c); // ==(lambda/kappa_c + (1.-lambda)/kappa_t)^-1
 	}	
Index: issm/trunk/src/c/analyses/ExtrapolationAnalysis.cpp
===================================================================
--- issm/trunk/src/c/analyses/ExtrapolationAnalysis.cpp	(revision 23389)
+++ issm/trunk/src/c/analyses/ExtrapolationAnalysis.cpp	(revision 23394)
@@ -65,5 +65,5 @@
 	femmodel->SetCurrentConfiguration(ExtrapolationAnalysisEnum);
 
-	if(VerboseSolution()) _printf0_("extrapolation of " << EnumToStringx(extvar_enum) << ": call computational core:\n");
+	if(VerboseSolution()) _printf0_("   extrapolation of " << EnumToStringx(extvar_enum) << ":\n");
 	solutionsequence_linear(femmodel);
 
Index: issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.cpp
===================================================================
--- issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 23389)
+++ issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 23394)
@@ -80,5 +80,4 @@
 	iomodel->FetchDataToInput(elements,"md.mask.ice_levelset",MaskIceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,"md.basalforcings.groundedice_melting_rate",BasalforcingsGroundediceMeltingRateEnum,0.);
-	iomodel->FetchDataToInput(elements,"md.basalforcings.floatingice_melting_rate",BasalforcingsFloatingiceMeltingRateEnum);
 	iomodel->FetchDataToInput(elements,"md.initialization.vx",VxEnum);
 	iomodel->FetchDataToInput(elements,"md.initialization.vy",VyEnum);
@@ -89,4 +88,29 @@
 		iomodel->FetchDataToInput(elements,"md.mesh.vertexonbase",MeshVertexonbaseEnum);
 		iomodel->FetchDataToInput(elements,"md.mesh.vertexonsurface",MeshVertexonsurfaceEnum);
+	}
+
+	/*Get what we need for ocean-induced basal melting*/
+	int basalforcing_model;
+	iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
+	switch(basalforcing_model){
+		case FloatingMeltRateEnum:
+			iomodel->FetchDataToInput(elements,"md.basalforcings.floatingice_melting_rate",BasalforcingsFloatingiceMeltingRateEnum);
+			break;
+		case LinearFloatingMeltRateEnum:
+			break;
+		case MismipFloatingMeltRateEnum:
+			break;
+		case MantlePlumeGeothermalFluxEnum:
+			break;
+		case SpatialLinearFloatingMeltRateEnum:
+			iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_melting_rate",BasalforcingsDeepwaterMeltingRateEnum);
+			iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_elevation",BasalforcingsDeepwaterElevationEnum);
+			iomodel->FetchDataToInput(elements,"md.basalforcings.upperwater_elevation",BasalforcingsUpperwaterElevationEnum);
+			break;
+		case BasalforcingsPicoEnum:
+			iomodel->FetchDataToInput(elements,"md.basalforcings.basin_id",BasalforcingsPicoBasinIdEnum);
+			break;
+		default:
+			_error_("Basal forcing model "<<EnumToStringx(basalforcing_model)<<" not supported yet");
 	}
 }/*}}}*/
Index: issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.cpp
===================================================================
--- issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.cpp	(revision 23389)
+++ issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.cpp	(revision 23394)
@@ -313,12 +313,14 @@
 	}
 	/*Intermediaries */
+	int        smb_model;
 	IssmDouble dt,scalar,water_head;
-	IssmDouble water_load,transfer;
+	IssmDouble water_load,transfer,runoff_value;
 	IssmDouble epl_storing,epl_transmitivity;
 	IssmDouble Jdet;
 	IssmDouble residual,connectivity;
 
-	IssmDouble *xyz_list     = NULL;
-	Input*      old_wh_input = NULL;
+	IssmDouble		*xyz_list							= NULL;
+	Input*				 old_wh_input					= NULL;
+	Input*				 surface_runoff_input = NULL;
 
 	/*Fetch number of nodes and dof for this finite element*/
@@ -334,15 +336,20 @@
 	//basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
 	basalelement ->FindParam(&dt,HydrologydtEnum);
-
-	Input* epl_thick_input = basalelement->GetInput(HydrologydcEplThicknessHydrostepEnum); _assert_(epl_thick_input);
-	Input* sed_head_input  = basalelement->GetInput(SedimentHeadHydrostepEnum); _assert_(sed_head_input);
-	Input* epl_head_input	 = basalelement->GetInput(EplHeadHydrostepEnum); _assert_(epl_head_input);
-	Input* water_input		 = basalelement->GetInput(BasalforcingsGroundediceMeltingRateEnum); _assert_(water_input);
-	Input* residual_input  = basalelement->GetInput(SedimentHeadResidualEnum); _assert_(residual_input);
-	Input* base_input			 = basalelement->GetInput(BaseEnum); _assert_(base_input);
+	basalelement ->FindParam(&smb_model,SmbEnum);
+
+	Input*	epl_thick_input			 = basalelement->GetInput(HydrologydcEplThicknessHydrostepEnum); _assert_(epl_thick_input);
+	Input*	sed_head_input			 = basalelement->GetInput(SedimentHeadHydrostepEnum); _assert_(sed_head_input);
+	Input*	epl_head_input			 = basalelement->GetInput(EplHeadHydrostepEnum); _assert_(epl_head_input);
+	Input*	basal_melt_input		 = basalelement->GetInput(BasalforcingsGroundediceMeltingRateEnum); _assert_(basal_melt_input);
+	Input*	residual_input			 = basalelement->GetInput(SedimentHeadResidualEnum); _assert_(residual_input);
+	Input*	base_input					 = basalelement->GetInput(BaseEnum); _assert_(base_input);
 
 	if(dt!= 0.){
 		old_wh_input = basalelement->GetInput(EplHeadOldEnum);            _assert_(old_wh_input);
 	}
+	if(smb_model==SMBgradientscomponentsEnum){
+		surface_runoff_input = basalelement->GetInput(SmbRunoffEnum); _assert_(surface_runoff_input);
+	}
+
 	/* Start  looping on the number of gaussian points: */
 	Gauss* gauss           = basalelement->NewGauss(2);
@@ -355,6 +362,8 @@
 
 		/*Loading term*/
-		water_input->GetInputValue(&water_load,gauss);
-		scalar = Jdet*gauss->weight*(water_load);
+		basal_melt_input->GetInputValue(&water_load,gauss);
+		if(surface_runoff_input) surface_runoff_input->GetInputValue(&runoff_value,gauss);
+		else                     runoff_value = 0.;
+		scalar = Jdet*gauss->weight*(water_load+runoff_value);
 		//scalar = Jdet*gauss->weight*(water_load)/epl_transmitivity;
 		if(dt!=0.) scalar = scalar*dt;
@@ -524,4 +533,5 @@
 	IssmDouble  EPLgrad2;
 	IssmDouble  EPL_N;
+	IssmDouble  opening,closing;
 
 	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
@@ -589,7 +599,12 @@
 				EPLgrad2 = (epl_slopeX[i]*epl_slopeX[i])+(epl_slopeY[i]*epl_slopeY[i]);
 				/*And proceed to the real thing*/
-				thickness[i] = old_thickness[i]/(1.0
-																				 -((rho_water*gravity*epl_conductivity*EPLgrad2*dt)/(rho_ice*latentheat))
-																				 +((2.0*A*dt*pow(EPL_N,n))/(pow(n,n))));
+				opening=(rho_water*gravity*epl_conductivity*EPLgrad2*dt)/(rho_ice*latentheat);
+				closing=(2.0*A*dt*pow(EPL_N,n))/(pow(n,n));
+				/*implicit*/
+				thickness[i] = old_thickness[i]/(1.0-opening+closing);
+				/*explicit*/
+				//thickness[i] = old_thickness[i]*(1.0+opening-closing);
+				/*centered*/
+				//thickness[i] = old_thickness[i]*(1.0+opening-closing)/(1.0-opening+closing);
 				/*Take care of otherthikening*/
 				if(thickness[i]>max_thick){
@@ -688,24 +703,20 @@
 		if(old_active[i]>0.){
 			vec_mask->SetValue(basalelement->nodes[i]->Sid(),1.,INS_VAL);
-			/* If epl thickness gets under colapse thickness, close the layer */
-			if(epl_thickness[i]<colapse_thick){
+			/* If epl thickness gets under colapse thickness, close the layer if there is no residual*/
+			if(epl_thickness[i]<colapse_thick && residual[i]<=0.){
 				vec_mask->SetValue(basalelement->nodes[i]->Sid(),0.,INS_VAL);
 				recurence->SetValue(basalelement->nodes[i]->Sid(),1.,INS_VAL);
 			}
-			/* //If epl head gets under base elevation, close the layer */
-			/* else if(eplhead[i]<(base[i]-1.0e-8)){ */
-			/* 	vec_mask->SetValue(basalelement->nodes[i]->Sid(),0.,INS_VAL); */
-			/* 	recurence->SetValue(basalelement->nodes[i]->Sid(),1.,INS_VAL); */
-			/* } */
-		}
-		/*If node is now closed bring its thickness back to initial*/
+		}
 		if (old_active[i]==0.){
-			epl_thickness[i]=init_thick;
 			/*Activate if we have a residual from sediment*/
 			if(residual[i]>0.){
 				vec_mask->SetValue(basalelement->nodes[i]->Sid(),1.,INS_VAL);
-				if(old_active[i]==0.){
-					recurence->SetValue(basalelement->nodes[i]->Sid(),1.,INS_VAL);
-				}
+				recurence->SetValue(basalelement->nodes[i]->Sid(),1.,INS_VAL);
+			}
+			else{
+				/*If node is now closed bring its thickness back to initial*/
+				epl_thickness[i]=init_thick;
+				vec_mask->SetValue(basalelement->nodes[i]->Sid(),0.,INS_VAL);
 			}
 		}
Index: issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.cpp
===================================================================
--- issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.cpp	(revision 23389)
+++ issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.cpp	(revision 23394)
@@ -10,5 +10,4 @@
 	return 1;
 }/*}}}*/
-
 void HydrologyDCInefficientAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
 
@@ -29,4 +28,6 @@
 
 	/*retrieve some parameters: */
+	bool   issmb;
+	iomodel->FindConstant(&issmb,"md.transient.issmb");
 	iomodel->FindConstant(&hydrology_model,"md.hydrology.model");
 
@@ -63,4 +64,8 @@
 		parameters->AddObject(new DoubleParam(HydrologydcSedimentlimitEnum,sedimentlimit));
 	}
+	if(!issmb){
+		parameters->AddObject(iomodel->CopyConstantObject("md.smb.model",SmbEnum));
+	}
+
   /*Requested outputs*/
   iomodel->FindConstant(&requestedoutputs,&numoutputs,"md.hydrology.requested_outputs");
@@ -69,5 +74,4 @@
   iomodel->DeleteData(&requestedoutputs,numoutputs,"md.hydrology.requested_outputs");
 }/*}}}*/
-
 void HydrologyDCInefficientAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
 
@@ -105,11 +109,10 @@
 		iomodel->FetchDataToInput(elements,"md.mesh.vertexonsurface",MeshVertexonsurfaceEnum);
 	}
-
 	if(isefficientlayer){
 		iomodel->FetchDataToInput(elements,"md.hydrology.mask_eplactive_node",HydrologydcMaskEplactiveNodeEnum);
 		iomodel->FetchDataToInput(elements,"md.initialization.epl_head",EplHeadHydrostepEnum);
 	}
-}/*}}}*/
-
+
+}/*}}}*/
 void HydrologyDCInefficientAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
 
@@ -127,5 +130,4 @@
 	iomodel->DeleteData(2,"md.mesh.vertexonbase","md.mesh.vertexonsurface");
 }/*}}}*/
-
 void HydrologyDCInefficientAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
 
@@ -137,5 +139,4 @@
 	IoModelToConstraintsx(constraints,iomodel,"md.hydrology.spcsediment_head",HydrologyDCInefficientAnalysisEnum,P1Enum);
 }/*}}}*/
-
 void HydrologyDCInefficientAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
 
@@ -172,14 +173,11 @@
 	_error_("not implemented");
 }/*}}}*/
-
 ElementVector* HydrologyDCInefficientAnalysis::CreateDVector(Element* element){/*{{{*/
 	/*Default, return NULL*/
 	return NULL;
 }/*}}}*/
-
 ElementMatrix* HydrologyDCInefficientAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
 _error_("Not implemented");
 }/*}}}*/
-
 ElementMatrix* HydrologyDCInefficientAnalysis::CreateKMatrix(Element* element){/*{{{*/
 
@@ -307,5 +305,4 @@
 	return Ke;
 }/*}}}*/
-
 ElementVector* HydrologyDCInefficientAnalysis::CreatePVector(Element* element){/*{{{*/
 
@@ -342,12 +339,14 @@
 	/*Intermediaries */
 	bool       active_element,isefficientlayer;
+	int        smb_model;
 	IssmDouble dt,scalar,sediment_storing;
 	IssmDouble water_head,sediment_transmitivity;
-	IssmDouble water_load,transfer;
+	IssmDouble water_load,runoff_value,transfer;
 	IssmDouble Jdet;
 
 	IssmDouble *xyz_list             = NULL;
 	Input*      active_element_input = NULL;
-	Input*      old_wh_input = NULL;
+	Input*      old_wh_input         = NULL;
+	Input*      surface_runoff_input = NULL;
 
 	/*Fetch number of nodes and dof for this finite element*/
@@ -361,16 +360,21 @@
 	basalelement->GetVerticesCoordinates(&xyz_list);
 	//basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
-	basalelement ->FindParam(&dt,HydrologydtEnum);
+	basalelement->FindParam(&dt,HydrologydtEnum);
 	basalelement->FindParam(&isefficientlayer,HydrologydcIsefficientlayerEnum);
-
-	Input* sed_head_input = basalelement->GetInput(SedimentHeadHydrostepEnum);
-	Input* epl_head_input = basalelement->GetInput(EplHeadHydrostepEnum);
-	Input* base_input		  = basalelement->GetInput(BaseEnum);
-	Input* water_input	  = basalelement->GetInput(BasalforcingsGroundediceMeltingRateEnum); _assert_(water_input);
-	Input* SedTrans_input = basalelement->GetInput(HydrologydcSedimentTransmitivityEnum); _assert_(SedTrans_input);
+	basalelement->FindParam(&smb_model,SmbEnum);
+
+	Input*	sed_head_input			 = basalelement->GetInput(SedimentHeadHydrostepEnum);
+	Input*	epl_head_input			 = basalelement->GetInput(EplHeadHydrostepEnum);
+	Input*	base_input					 = basalelement->GetInput(BaseEnum);
+	Input*	basal_melt_input		 = basalelement->GetInput(BasalforcingsGroundediceMeltingRateEnum); _assert_(basal_melt_input);
+	Input*	SedTrans_input			 = basalelement->GetInput(HydrologydcSedimentTransmitivityEnum); _assert_(SedTrans_input);
 
 	if(dt!= 0.){
 		old_wh_input = basalelement->GetInput(SedimentHeadOldEnum);                  _assert_(old_wh_input);
 	}
+	if(smb_model==SMBgradientscomponentsEnum){
+		surface_runoff_input = basalelement->GetInput(SmbRunoffEnum); _assert_(surface_runoff_input);
+	}
+
 	/*Transfer related Inputs*/
 	if(isefficientlayer){
@@ -388,6 +392,8 @@
 		/*Loading term*/
 		if(!isefficientlayer){
-			water_input->GetInputValue(&water_load,gauss);
-			scalar = Jdet*gauss->weight*(water_load);
+			basal_melt_input->GetInputValue(&water_load,gauss);
+			if(surface_runoff_input) surface_runoff_input->GetInputValue(&runoff_value,gauss);
+			else                     runoff_value = 0.;
+			scalar = Jdet*gauss->weight*(water_load+runoff_value);
 			//scalar = Jdet*gauss->weight*(water_load)/sediment_transmitivity;
 			if(dt!=0.) scalar = scalar*dt;
@@ -400,6 +406,8 @@
 			active_element_input->GetInputValue(&active_element);
 			if(!active_element){
-				water_input->GetInputValue(&water_load,gauss);
-				scalar = Jdet*gauss->weight*(water_load);
+				basal_melt_input->GetInputValue(&water_load,gauss);
+				if(surface_runoff_input) surface_runoff_input->GetInputValue(&runoff_value,gauss);
+				else                     runoff_value = 0.;
+				scalar = Jdet*gauss->weight*(water_load+runoff_value);
 				//scalar = Jdet*gauss->weight*(water_load)/sediment_transmitivity;
 				if(dt!=0.) scalar = scalar*dt;
@@ -444,5 +452,4 @@
 	return pe;
 }/*}}}*/
-
 void HydrologyDCInefficientAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2.
@@ -472,13 +479,10 @@
 	xDelete<IssmDouble>(dbasis);
 }/*}}}*/
-
 void HydrologyDCInefficientAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
 	element->GetSolutionFromInputsOneDof(solution,SedimentHeadHydrostepEnum);
 }/*}}}*/
-
 void HydrologyDCInefficientAnalysis::GradientJ(Vector<IssmDouble>* gradient,Element* element,int control_type,int control_index){/*{{{*/
 	_error_("Not implemented yet");
 }/*}}}*/
-
 void HydrologyDCInefficientAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
 
@@ -514,5 +518,4 @@
 	/*Use the dof list to index into the solution vector: */
 
-	/*need to introduce thawed test herre*/
 	for(int i=0;i<numnodes;i++){
 		values[i] =solution[doflist[i]];
@@ -542,5 +545,13 @@
 		kappa=kmax*pow(10.,penalty_factor);
 
+
+		Input* thawed_element_input = basalelement->GetInput(HydrologydcMaskThawedEltEnum); _assert_(thawed_element_input);
+		thawed_element_input->GetInputValue(&thawed_element);
+
 		for(int i=0;i<numnodes;i++){
+			/*frozen elements heads are set to base elevation*/
+			if(!thawed_element){
+				values[i]=base[i];
+			}
 			GetHydrologyDCInefficientHmax(&h_max,basalelement,basalelement->GetNode(i));
 			if(values[i]>h_max) {
@@ -551,7 +562,6 @@
 				residual[i] = 0.;
 			}
-			//adding base in min to take into account heads under bed wich don't change N
-			//pressure[i]=(rho_ice*g*thickness[i])-(rho_freshwater*g*(max((min(h_max,values[i])-base[i]),0.0)));
 			pressure[i]=(rho_ice*g*thickness[i])-(rho_freshwater*g*(values[i]-base[i]));
+
 		}
 		xDelete<IssmDouble>(thickness);
@@ -575,10 +585,8 @@
 	}
 }/*}}}*/
-
 void HydrologyDCInefficientAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
 	/*Default, do nothing*/
 	return;
 }/*}}}*/
-
 IssmDouble HydrologyDCInefficientAnalysis::SedimentStoring(Element* element,Gauss* gauss,Input* sed_head_input, Input* base_input){/*{{{*/
 	int unconf_scheme;
@@ -620,5 +628,4 @@
 	return sediment_storing;
 }/*}}}*/
-
 IssmDouble HydrologyDCInefficientAnalysis::SedimentTransmitivity(Element* element,Gauss* gauss,Input* sed_head_input, Input* base_input,Input* SedTrans_input){/*{{{*/
 	int unconf_scheme;
@@ -630,7 +637,5 @@
 	IssmDouble base_elev,prestep_head,water_sheet;
 	IssmDouble sediment_thickness       = element->GetMaterialParameter(HydrologydcSedimentThicknessEnum);
-	bool isthermal;
-
-	element->FindParam(&isthermal,TransientIsthermalEnum);
+
 	element->FindParam(&unconf_scheme,HydrologydcUnconfinedFlagEnum);
 	SedTrans_input->GetInputValue(&FullLayer_transmitivity,gauss);
@@ -657,5 +662,4 @@
 	return sediment_transmitivity;
 }/*}}}*/
-
 void  HydrologyDCInefficientAnalysis::GetHydrologyDCInefficientHmax(IssmDouble* ph_max,Element* element, Node* innode){/*{{{*/
 
@@ -693,5 +697,4 @@
 }
 /*}}}*/
-
 IssmDouble HydrologyDCInefficientAnalysis::GetHydrologyKMatrixTransfer(Element* element){/*{{{*/
 
@@ -715,5 +718,4 @@
 	return transfer;
 }/*}}}*/
-
 IssmDouble HydrologyDCInefficientAnalysis::GetHydrologyPVectorTransfer(Element* element, Gauss* gauss, Input* epl_head_input){/*{{{*/
 
@@ -740,5 +742,4 @@
 	return transfer;
 }/*}}}*/
-
 void HydrologyDCInefficientAnalysis::ElementizeEplMask(FemModel* femmodel){/*{{{*/
 
@@ -759,6 +760,5 @@
 	}
 }/*}}}*/
-
-void  HydrologyDCInefficientAnalysis::HydrologyIDSGetMask(Vector<IssmDouble>* vec_mask, Element* element){
+void  HydrologyDCInefficientAnalysis::HydrologyIDSGetMask(Vector<IssmDouble>* vec_mask, Element* element){/*{{{*/
 	bool        active_element;
 	int         domaintype;
@@ -801,5 +801,5 @@
 	xDelete<IssmDouble>(meltingrate);
 	xDelete<IssmDouble>(groundedice);
-}
+}/*}}}*/
 void HydrologyDCInefficientAnalysis::ElementizeIdsMask(FemModel* femmodel){/*{{{*/
 
@@ -820,5 +820,4 @@
 	}
 }/*}}}*/
-
 void HydrologyDCInefficientAnalysis::HydrologyIdsGetActive(Vector<IssmDouble>* active_vec, Element* element){/*{{{*/
 	/*Constants*/
Index: issm/trunk/src/c/analyses/LevelsetAnalysis.cpp
===================================================================
--- issm/trunk/src/c/analyses/LevelsetAnalysis.cpp	(revision 23389)
+++ issm/trunk/src/c/analyses/LevelsetAnalysis.cpp	(revision 23394)
@@ -131,5 +131,5 @@
 	femmodel->SetCurrentConfiguration(LevelsetAnalysisEnum);
 
-	if(VerboseSolution()) _printf0_("call computational core:\n");
+	if(VerboseSolution()) _printf0_("   call computational core:\n");
 	if(stabilization==4){
 		solutionsequence_fct(femmodel);
Index: issm/trunk/src/c/analyses/MasstransportAnalysis.cpp
===================================================================
--- issm/trunk/src/c/analyses/MasstransportAnalysis.cpp	(revision 23389)
+++ issm/trunk/src/c/analyses/MasstransportAnalysis.cpp	(revision 23394)
@@ -124,5 +124,4 @@
 	bool   isoceancoupling;
 	bool   issmb;
-	int    basalforcingsmodel;
 
 	/*Fetch data needed: */
@@ -133,5 +132,4 @@
 	iomodel->FindConstant(&isoceancoupling,"md.transient.isoceancoupling");
 	iomodel->FindConstant(&issmb,"md.transient.issmb");
-	iomodel->FindConstant(&basalforcingsmodel,"md.basalforcings.model");
 
 	/*Finite element type*/
@@ -158,9 +156,4 @@
 	iomodel->FetchDataToInput(elements,"md.mask.groundedice_levelset",MaskGroundediceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,"md.basalforcings.groundedice_melting_rate",BasalforcingsGroundediceMeltingRateEnum);
-	if (basalforcingsmodel==SpatialLinearFloatingMeltRateEnum){
-		iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_melting_rate",BasalforcingsDeepwaterMeltingRateEnum);
-		iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_elevation",BasalforcingsDeepwaterElevationEnum);
-		iomodel->FetchDataToInput(elements,"md.basalforcings.upperwater_elevation",BasalforcingsUpperwaterElevationEnum);
-	}
 	iomodel->FetchDataToInput(elements,"md.initialization.vx",VxEnum);
 	iomodel->FetchDataToInput(elements,"md.initialization.vy",VyEnum);
@@ -181,4 +174,9 @@
 			break;
 		case MantlePlumeGeothermalFluxEnum:
+			break;
+		case SpatialLinearFloatingMeltRateEnum:
+			iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_melting_rate",BasalforcingsDeepwaterMeltingRateEnum);
+			iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_elevation",BasalforcingsDeepwaterElevationEnum);
+			iomodel->FetchDataToInput(elements,"md.basalforcings.upperwater_elevation",BasalforcingsUpperwaterElevationEnum);
 			break;
 		case BasalforcingsPicoEnum:
@@ -631,7 +629,7 @@
 }/*}}}*/
 void           MasstransportAnalysis::GetB(IssmDouble* B,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
-	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2. 
+	/*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2.
 	 * For node i, Bi can be expressed in the actual coordinate system
-	 * by: 
+	 * by:
 	 *       Bi=[ N ]
 	 *          [ N ]
@@ -659,7 +657,7 @@
 }/*}}}*/
 void           MasstransportAnalysis::GetBprime(IssmDouble* Bprime,Element* element,int dim,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
-	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
+	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2.
 	 * For node i, Bi' can be expressed in the actual coordinate system
-	 * by: 
+	 * by:
 	 *       Bi_prime=[ dN/dx ]
 	 *                [ dN/dy ]
Index: issm/trunk/src/c/analyses/SmbAnalysis.cpp
===================================================================
--- issm/trunk/src/c/analyses/SmbAnalysis.cpp	(revision 23389)
+++ issm/trunk/src/c/analyses/SmbAnalysis.cpp	(revision 23394)
@@ -5,4 +5,7 @@
 #include "../modules/modules.h"
 
+// FIX
+#include "./shared/io/Print/Print.h"
+
 /*Model processing*/
 void SmbAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
@@ -21,5 +24,5 @@
 
 	int    smb_model;
-	bool   isdelta18o,ismungsm,isd18opd,issetpddfac,isprecipscaled,istemperaturescaled;
+	bool   isdelta18o,ismungsm,isd18opd,issetpddfac,isprecipscaled,istemperaturescaled,isfirnwarming;
 
 	/*Update elements: */
@@ -35,5 +38,4 @@
 	/*Figure out smb model: */
 	iomodel->FindConstant(&smb_model,"md.smb.model");
-
 	switch(smb_model){
 		case SMBforcingEnum:
@@ -88,4 +90,14 @@
 			}
 			break;
+		case SMBpddSicopolisEnum:
+			iomodel->FetchDataToInput(elements,"md.smb.s0p",SmbS0pEnum);
+			iomodel->FetchDataToInput(elements,"md.smb.s0t",SmbS0tEnum);
+			iomodel->FindConstant(&isfirnwarming,"md.smb.isfirnwarming");
+			iomodel->FetchDataToInput(elements,"md.smb.smb_corr",SmbSmbCorrEnum);
+			iomodel->FetchDataToInput(elements,"md.smb.precipitation",SmbPrecipitationEnum);
+			iomodel->FetchDataToInput(elements,"md.smb.monthlytemperatures",SmbMonthlytemperaturesEnum);
+			iomodel->FetchDataToInput(elements,"md.smb.precipitation_anomaly",SmbPrecipitationsAnomalyEnum);
+			iomodel->FetchDataToInput(elements,"md.smb.temperature_anomaly",SmbTemperaturesAnomalyEnum);
+			break;
 		case SMBd18opddEnum:
 			iomodel->FindConstant(&istemperaturescaled,"md.smb.istemperaturescaled");
@@ -139,4 +151,10 @@
 			iomodel->FetchDataToInput(elements,"md.smb.refreeze",SmbRefreezeEnum,0.);
 			break;
+		case SMBgradientscomponentsEnum:
+			iomodel->FetchDataToInput(elements,"md.smb.accualti",SmbAccualtiEnum);
+			iomodel->FetchDataToInput(elements,"md.smb.accugrad",SmbAccugradEnum);
+			iomodel->FetchDataToInput(elements,"md.smb.runoffalti",SmbRunoffaltiEnum);
+			iomodel->FetchDataToInput(elements,"md.smb.runoffgrad",SmbRunoffgradEnum);
+			break;
 		default:
 			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
@@ -148,5 +166,5 @@
 	int     numoutputs;
 	char**  requestedoutputs = NULL;
-	bool    isdelta18o,ismungsm,isd18opd,issetpddfac,interp;
+	bool    isdelta18o,ismungsm,isd18opd,issetpddfac,interp,isfirnwarming;
 	int     smb_model;
 	IssmDouble *temp = NULL;
@@ -215,4 +233,7 @@
 			}
 			break;
+		case SMBpddSicopolisEnum:
+			parameters->AddObject(iomodel->CopyConstantObject("md.smb.isfirnwarming",SmbIsfirnwarmingEnum));
+			break;
 		case SMBd18opddEnum:
 			parameters->AddObject(iomodel->CopyConstantObject("md.smb.ismungsm",SmbIsmungsmEnum));
@@ -246,4 +267,18 @@
 			/*Nothing to add to parameters*/
 			break;
+		case SMBgradientscomponentsEnum:
+				parameters->AddObject(iomodel->CopyConstantObject("md.smb.accualti",SmbAccualtiEnum));
+				parameters->AddObject(iomodel->CopyConstantObject("md.smb.accugrad",SmbAccugradEnum));
+				parameters->AddObject(iomodel->CopyConstantObject("md.smb.runoffalti",SmbRunoffaltiEnum));
+				parameters->AddObject(iomodel->CopyConstantObject("md.smb.runoffgrad",SmbRunoffgradEnum));
+
+			  iomodel->FetchData(&temp,&N,&M,"md.smb.accuref"); _assert_(N==2);
+			  parameters->AddObject(new TransientParam(SmbAccurefEnum,&temp[0],&temp[M],interp,M));
+			  iomodel->DeleteData(temp,"md.smb.accuref");
+
+			  iomodel->FetchData(&temp,&N,&M,"md.smb.runoffref"); _assert_(N==2);
+			  parameters->AddObject(new TransientParam(SmbRunoffrefEnum,&temp[0],&temp[M],interp,M));
+			  iomodel->DeleteData(temp,"md.smb.runoffref");
+			break;
 		default:
 			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
@@ -280,11 +315,15 @@
 				if(VerboseSolution()) _printf0_("   call Delta18oParameterization module\n");
 				Delta18oParameterizationx(femmodel);
-			} 
+			}
 			if(ismungsm){
 				if(VerboseSolution()) _printf0_("   call MungsmtpParameterization module\n");
 				MungsmtpParameterizationx(femmodel);
-			} 
+			}
 			if(VerboseSolution()) _printf0_("   call positive degree day module\n");
 			PositiveDegreeDayx(femmodel);
+			break;
+		case SMBpddSicopolisEnum:
+			if(VerboseSolution()) _printf0_("   call SICOPOLIS positive degree day module\n");
+			PositiveDegreeDaySicopolisx(femmodel);
 			break;
 		case SMBd18opddEnum:
@@ -296,5 +335,5 @@
 				if(VerboseSolution()) _printf0_("   call positive degree day module\n");
 				PositiveDegreeDayx(femmodel);
-			} 
+			}
 			break;
 		case SMBgradientsEnum:
@@ -321,4 +360,8 @@
 			/*Nothing to be done*/
 			break;
+		case SMBgradientscomponentsEnum:
+			if(VerboseSolution())_printf0_("	call smb gradients components module\n");
+			SmbGradientsComponentsx(femmodel);
+			break;
 		default:
 			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
Index: issm/trunk/src/c/analyses/StressbalanceAnalysis.cpp
===================================================================
--- issm/trunk/src/c/analyses/StressbalanceAnalysis.cpp	(revision 23389)
+++ issm/trunk/src/c/analyses/StressbalanceAnalysis.cpp	(revision 23394)
@@ -766,5 +766,29 @@
 	if(isFS){
 		iomodel->FetchDataToInput(elements,"md.initialization.pressure",PressureEnum,0.);
-		iomodel->FetchDataToInput(elements,"md.basalforcings.floatingice_melting_rate",BasalforcingsFloatingiceMeltingRateEnum,0.);
+
+		/*Add basal forcings to compute melt rate*/
+		int basalforcing_model;
+		iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
+		switch(basalforcing_model){
+			case FloatingMeltRateEnum:
+				iomodel->FetchDataToInput(elements,"md.basalforcings.floatingice_melting_rate",BasalforcingsFloatingiceMeltingRateEnum);
+				break;
+			case LinearFloatingMeltRateEnum:
+				break;
+			case MismipFloatingMeltRateEnum:
+				break;
+			case MantlePlumeGeothermalFluxEnum:
+				break;
+			case SpatialLinearFloatingMeltRateEnum:
+				iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_melting_rate",BasalforcingsDeepwaterMeltingRateEnum);
+				iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_elevation",BasalforcingsDeepwaterElevationEnum);
+				iomodel->FetchDataToInput(elements,"md.basalforcings.upperwater_elevation",BasalforcingsUpperwaterElevationEnum);
+				break;
+			case BasalforcingsPicoEnum:
+				iomodel->FetchDataToInput(elements,"md.basalforcings.basin_id",BasalforcingsPicoBasinIdEnum);
+				break;
+			default:
+				_error_("Basal forcing model "<<EnumToStringx(basalforcing_model)<<" not supported yet");
+		}
 	}
 	/*LATH parameters*/
@@ -844,4 +868,6 @@
 			iomodel->FetchDataToInput(elements,"md.friction.till_friction_angle",FrictionTillFrictionAngleEnum);
 			iomodel->FetchDataToInput(elements,"md.friction.sediment_compressibility_coefficient",FrictionSedimentCompressibilityCoefficientEnum);
+			iomodel->FetchDataToInput(elements,"md.hydrology.watercolumn_max",HydrologyWatercolumnMaxEnum);
+			iomodel->FetchDataToInput(elements,"md.initialization.watercolumn",WatercolumnEnum,0.);
 			break;
 		default:
@@ -945,7 +971,9 @@
 		int solver_type;
 		PetscOptionsDetermineSolverType(&solver_type);
+
 		if(solver_type==FSSolverEnum) is_schur_cg_solver = true;
 		#endif
 
+		
 		if(is_schur_cg_solver)
 		 solutionsequence_schurcg(femmodel);
@@ -3270,13 +3298,12 @@
 		element->NodalFunctionsPressure(pbasis,gauss);
 
-		if(dim==3){
+		if(dim==3 || dim==2){
 			/*Pressure mass matrix*/
 			for(int k=0;k<pnumnodes;k++){
 				for(int j=0;j<pnumnodes;j++){
-					Ke->values[(3*vnumnodes+k)*numdof+3*vnumnodes+j] += gauss->weight*Jdet*(pbasis[j]*pbasis[k]);
+					Ke->values[(dim*vnumnodes+k)*numdof+dim*vnumnodes+j] += gauss->weight*Jdet*(pbasis[j]*pbasis[k]);
 				}
 			}
-		}
-		else{
+		}else{
 			_error_("STOP");
 		}
@@ -3289,4 +3316,61 @@
 	return Ke;
 }/*}}}*/
+ElementMatrix* StressbalanceAnalysis::CreateSchurPrecondMatrix(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	int         i,dim;
+	IssmDouble  viscosity,FSreconditioning,Jdet;
+	IssmDouble *xyz_list = NULL;
+
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int vnumnodes = element->NumberofNodesVelocity();
+	int pnumnodes = element->NumberofNodesPressure();
+	int numdof    = vnumnodes*dim + pnumnodes;
+
+	/*Initialize Element matrix and vectors*/
+	ElementMatrix* Ke  = element->NewElementMatrix(FSvelocityEnum);
+	IssmDouble* pbasis = xNew<IssmDouble>(pnumnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	//element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
+	Input* vx_input=element->GetInput(VxEnum);     _assert_(vx_input);
+	Input* vy_input=element->GetInput(VyEnum);     _assert_(vy_input);
+	Input* vz_input = NULL;
+	if(dim==3){vz_input=element->GetInput(VzEnum); _assert_(vz_input);}
+
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss = element->NewGauss(5);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctionsPressure(pbasis,gauss);
+		element->material->ViscosityFS(&viscosity,dim,xyz_list,gauss,vx_input,vy_input,vz_input);
+
+
+		if(dim==3 || dim==2){
+			/*Pressure mass matrix*/
+			for(int k=0;k<pnumnodes;k++){
+				for(int j=0;j<pnumnodes;j++){
+					Ke->values[(dim*vnumnodes+k)*numdof+dim*vnumnodes+j] += gauss->weight*1./viscosity*Jdet*(pbasis[j]*pbasis[k]);
+				}
+			}
+		}else{
+			_error_("STOP");
+		}
+	}
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(pbasis);
+	return Ke;
+}/*}}}*/
+
 ElementMatrix* StressbalanceAnalysis::CreateKMatrixFSViscousLA(Element* element){/*{{{*/
 
Index: issm/trunk/src/c/analyses/StressbalanceAnalysis.h
===================================================================
--- issm/trunk/src/c/analyses/StressbalanceAnalysis.h	(revision 23389)
+++ issm/trunk/src/c/analyses/StressbalanceAnalysis.h	(revision 23394)
@@ -75,4 +75,5 @@
 		ElementMatrix* CreateKMatrixFSViscousXTH(Element* element);
 		ElementMatrix* CreatePressureMassMatrix(Element* element);
+		ElementMatrix* CreateSchurPrecondMatrix(Element* element);
 		ElementVector* CreatePVectorFS(Element* element);
 		ElementVector* CreatePVectorFSFriction(Element* element);
Index: issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.cpp
===================================================================
--- issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 23389)
+++ issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 23394)
@@ -111,6 +111,31 @@
 	}
 	iomodel->FetchDataToInput(elements,"md.basalforcings.groundedice_melting_rate",BasalforcingsGroundediceMeltingRateEnum);
-	iomodel->FetchDataToInput(elements,"md.basalforcings.floatingice_melting_rate",BasalforcingsFloatingiceMeltingRateEnum,0.);
 	//iomodel->FetchDataToInput(elements,"md.smb.mass_balance",SmbMassBalanceEnum);
+
+
+	/*Add basal forcings to compute melt rate*/
+	int basalforcing_model;
+	iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
+	switch(basalforcing_model){
+		case FloatingMeltRateEnum:
+			iomodel->FetchDataToInput(elements,"md.basalforcings.floatingice_melting_rate",BasalforcingsFloatingiceMeltingRateEnum);
+			break;
+		case LinearFloatingMeltRateEnum:
+			break;
+		case MismipFloatingMeltRateEnum:
+			break;
+		case MantlePlumeGeothermalFluxEnum:
+			break;
+		case SpatialLinearFloatingMeltRateEnum:
+			iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_melting_rate",BasalforcingsDeepwaterMeltingRateEnum);
+			iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_elevation",BasalforcingsDeepwaterElevationEnum);
+			iomodel->FetchDataToInput(elements,"md.basalforcings.upperwater_elevation",BasalforcingsUpperwaterElevationEnum);
+			break;
+		case BasalforcingsPicoEnum:
+			iomodel->FetchDataToInput(elements,"md.basalforcings.basin_id",BasalforcingsPicoBasinIdEnum);
+			break;
+		default:
+			_error_("Basal forcing model "<<EnumToStringx(basalforcing_model)<<" not supported yet");
+	}
 	iomodel->FetchDataToInput(elements,"md.initialization.vx",VxEnum,0.);
 	iomodel->FetchDataToInput(elements,"md.initialization.vy",VyEnum,0.);
Index: issm/trunk/src/c/analyses/ThermalAnalysis.cpp
===================================================================
--- issm/trunk/src/c/analyses/ThermalAnalysis.cpp	(revision 23389)
+++ issm/trunk/src/c/analyses/ThermalAnalysis.cpp	(revision 23394)
@@ -33,6 +33,7 @@
 		int smb_model;
 		iomodel->FindConstant(&smb_model,"md.smb.model");
-		if(smb_model==SMBpddEnum) isdynamic=true;
-		if(smb_model==SMBd18opddEnum) isdynamic=true;
+		if(smb_model==SMBpddEnum)				isdynamic=true;
+		if(smb_model==SMBd18opddEnum)			isdynamic=true;
+		if(smb_model==SMBpddSicopolisEnum)  isdynamic=true;
 	}
 	else{
Index: issm/trunk/src/c/classes/Elements/Element.cpp
===================================================================
--- issm/trunk/src/c/classes/Elements/Element.cpp	(revision 23389)
+++ issm/trunk/src/c/classes/Elements/Element.cpp	(revision 23394)
@@ -653,4 +653,74 @@
 	xDelete<IssmDouble>(tmp);
 
+}
+/*}}}*/
+void       Element::SmbGradCompParameterization(void){/*{{{*/
+
+	/*Are we on the base? If not, return*/
+	if(!IsOnBase()) return;
+	int        numvertices = this->GetNumberOfVertices();
+
+	int        i;
+	IssmDouble accuref, runoffref; //reference values at given altitude
+	IssmDouble accualti, runoffalti; //reference altitudes
+	IssmDouble accugrad, runoffgrad; //gradients from reference altitude
+	IssmDouble rho_water, rho_ice;
+	IssmDouble time;
+
+	IssmDouble*		smb		 = xNew<IssmDouble>(numvertices);
+	IssmDouble*		surf	 = xNew<IssmDouble>(numvertices);
+	IssmDouble*		accu	 = xNew<IssmDouble>(numvertices);
+	IssmDouble*		runoff = xNew<IssmDouble>(numvertices);
+
+	/*Get material parameters :*/
+	rho_water=this->matpar->GetMaterialParameter(MaterialsRhoSeawaterEnum);
+	rho_ice=this->matpar->GetMaterialParameter(MaterialsRhoIceEnum);
+
+	/*Recover parameters*/
+	parameters->FindParam(&time,TimeEnum);
+	parameters->FindParam(&accualti,SmbAccualtiEnum);
+	parameters->FindParam(&accugrad,SmbAccugradEnum);
+	parameters->FindParam(&runoffalti,SmbRunoffaltiEnum);
+	parameters->FindParam(&runoffgrad,SmbRunoffgradEnum);
+
+	/*Recover reference values at current time*/
+	parameters->FindParam(&accuref,SmbAccurefEnum,time);
+	parameters->FindParam(&runoffref,SmbRunoffrefEnum,time);
+
+	/*Recover surface elevation*/
+	GetInputListOnVertices(&surf[0],SurfaceEnum);
+
+	/*Compute the temperature and precipitation*/
+	for(int iv=0;iv<numvertices;iv++){
+		accu[iv]=max(0.,(accuref+(surf[iv]-accualti)*accugrad));
+		runoff[iv]=max(0.,(runoffref+(surf[iv]-runoffalti)*runoffgrad));
+		smb[iv]=(accu[iv]-runoff[iv])*rho_ice/rho_water;
+	}
+	switch(this->ObjectEnum()){
+	case TriaEnum:
+		this->inputs->AddInput(new TriaInput(SmbMassBalanceEnum,&smb[0],P1Enum));
+		this->inputs->AddInput(new TriaInput(SmbRunoffEnum,&runoff[0],P1Enum));
+		break;
+	case PentaEnum:
+		this->inputs->AddInput(new PentaInput(SmbMassBalanceEnum,&smb[0],P1Enum));
+		this->inputs->AddInput(new PentaInput(SmbRunoffEnum,&runoff[0],P1Enum));
+		this->InputExtrude(SmbMassBalanceEnum,-1);
+		this->InputExtrude(SmbRunoffEnum,-1);
+		break;
+	case TetraEnum:
+		this->inputs->AddInput(new TetraInput(SmbMassBalanceEnum,&smb[0],P1Enum));
+		this->inputs->AddInput(new TetraInput(SmbRunoffEnum,&runoff[0],P1Enum));
+		this->InputExtrude(SmbMassBalanceEnum,-1);
+		this->InputExtrude(SmbRunoffEnum,-1);
+		break;
+	default: _error_("Not implemented yet");
+	}
+	/* this->AddInput(SmbMassBalanceEnum,smb,P1Enum); */
+	/* this->AddInput(SmbRunoffEnum,runoff,P1Enum); */
+	/*clean-up*/
+	xDelete<IssmDouble>(surf);
+	xDelete<IssmDouble>(accu);
+	xDelete<IssmDouble>(runoff);
+	xDelete<IssmDouble>(smb);
 }
 /*}}}*/
@@ -2561,4 +2631,169 @@
 }
 /*}}}*/
+void       Element::PositiveDegreeDaySicopolis(bool isfirnwarming){/*{{{*/
+
+	/* General FIXMEs: get Tmelting point, pddicefactor, pddsnowfactor, sigma from parameters/user input */
+
+	int  numvertices = this->GetNumberOfVertices();
+
+	int        i;
+	IssmDouble* smb=xNew<IssmDouble>(numvertices);		// surface mass balance
+	IssmDouble* melt=xNew<IssmDouble>(numvertices);		// melting comp. of surface mass balance
+	IssmDouble* accu=xNew<IssmDouble>(numvertices);		// accuumulation comp. of surface mass balance
+	IssmDouble* melt_star=xNew<IssmDouble>(numvertices);
+	IssmDouble* monthlytemperatures=xNew<IssmDouble>(12*numvertices);
+	IssmDouble* monthlyprec=xNew<IssmDouble>(12*numvertices);
+	IssmDouble* yearlytemperatures=xNew<IssmDouble>(numvertices); memset(yearlytemperatures, 0., numvertices*sizeof(IssmDouble));
+	IssmDouble* s=xNew<IssmDouble>(numvertices);			// actual surface height
+	IssmDouble* s0p=xNew<IssmDouble>(numvertices);		// reference elevation for precip.
+	IssmDouble* s0t=xNew<IssmDouble>(numvertices);		// reference elevation for temperature
+	IssmDouble* smbcorr=xNew<IssmDouble>(numvertices); // surface mass balance correction; will be added after pdd call
+	IssmDouble* p_ampl=xNew<IssmDouble>(numvertices);	// precip anomaly
+	IssmDouble* t_ampl=xNew<IssmDouble>(numvertices);	// remperature anomaly
+	IssmDouble rho_water,rho_ice,desfac,rlaps;
+	IssmDouble inv_twelve=1./12.;								//factor for monthly average
+	IssmDouble time,yts,time_yr;
+
+	/*Get material parameters :*/
+	rho_water=this->matpar->GetMaterialParameter(MaterialsRhoSeawaterEnum);
+	rho_ice=this->matpar->GetMaterialParameter(MaterialsRhoIceEnum);
+
+	/*Get parameters for height corrections*/
+	desfac=this->matpar->GetMaterialParameter(SmbDesfacEnum);
+	rlaps=this->matpar->GetMaterialParameter(SmbRlapsEnum);
+
+	/*Recover monthly temperatures and precipitation*/
+	Input*     input=this->inputs->GetInput(SmbMonthlytemperaturesEnum); _assert_(input);
+	Input*     input2=this->inputs->GetInput(SmbPrecipitationEnum); _assert_(input2);
+	/*Recover smb correction term */
+	Input*     input3=this->inputs->GetInput(SmbSmbCorrEnum); _assert_(input3);
+
+	/* Get time */
+	this->parameters->FindParam(&time,TimeEnum);
+	this->parameters->FindParam(&yts,ConstantsYtsEnum);
+	time_yr=floor(time/yts)*yts;
+
+	/* Set parameters for finrnwarming */
+	IssmDouble MU_0         = 9.7155; //Firn-warming correction, in (d*deg C)/(mm WE)
+	IssmDouble mu           = MU_0*(1000.0*86400.0)*(rho_ice/rho_water);   // (d*deg C)/(mm WE) --> (s*deg C)/(m IE)
+
+	/*loop over vertices: */
+	Gauss* gauss=this->NewGauss();
+	for(int month=0;month<12;month++){
+		for(int iv=0;iv<numvertices;iv++){
+			gauss->GaussVertex(iv);
+			input->GetInputValue(&monthlytemperatures[iv*12+month],gauss,(month+1)/12.*yts);
+			monthlytemperatures[iv*12+month]=monthlytemperatures[iv*12+month]-273.15; // conversion from Kelvin to celcius for PDD module
+			input2->GetInputValue(&monthlyprec[iv*12+month],gauss,(month+1)/12.*yts);
+			monthlyprec[iv*12+month]=monthlyprec[iv*12+month]*yts;
+		}
+	}
+
+	/*Recover info at the vertices: */
+	GetInputListOnVertices(&s[0],SurfaceEnum);
+	GetInputListOnVertices(&s0p[0],SmbS0pEnum);
+	GetInputListOnVertices(&s0t[0],SmbS0tEnum);
+	GetInputListOnVertices(&smbcorr[0],SmbSmbCorrEnum);
+	GetInputListOnVertices(&t_ampl[0],SmbTemperaturesAnomalyEnum);
+	GetInputListOnVertices(&p_ampl[0],SmbPrecipitationsAnomalyEnum);
+
+	/*measure the surface mass balance*/
+	for (int iv = 0; iv<numvertices; iv++){
+		smb[iv]=PddSurfaceMassBalanceSicopolis(&monthlytemperatures[iv*12], &monthlyprec[iv*12],
+					&melt[iv], &accu[iv], &melt_star[iv], &t_ampl[iv], &p_ampl[iv], yts, s[iv],
+					desfac, s0t[iv], s0p[iv],rlaps,rho_water,rho_ice);
+
+		/* make correction */
+		smb[iv] = smb[iv]+smbcorr[iv];
+		/*Get yearlytemperatures */
+		for(int month=0;month<12;month++) yearlytemperatures[iv]=yearlytemperatures[iv]+((monthlytemperatures[iv*12+month]+273.15)+t_ampl[iv])*inv_twelve; // Has to be in Kelvin
+
+		if(isfirnwarming){
+			if(melt_star[iv]>=melt[iv]){
+				yearlytemperatures[iv]= yearlytemperatures[iv]+mu*(melt_star[iv]-melt[iv]);
+			}
+			else{
+				yearlytemperatures[iv]= yearlytemperatures[iv];
+			}
+		}
+		if (yearlytemperatures[iv]>273.15) yearlytemperatures[iv]=273.15;
+	}
+
+	switch(this->ObjectEnum()){
+		case TriaEnum:
+			// this->inputs->AddInput(new TriaInput(TemperatureEnum,&yearlytemperatures[0],P1Enum));
+			this->inputs->AddInput(new TriaInput(TemperaturePDDEnum,&yearlytemperatures[0],P1Enum));
+			this->inputs->AddInput(new TriaInput(SmbMassBalanceEnum,&smb[0],P1Enum));
+			this->inputs->AddInput(new TriaInput(SmbAccumulationEnum,&accu[0],P1Enum));
+			this->inputs->AddInput(new TriaInput(SmbMeltEnum,&melt[0],P1Enum));
+			break;
+		case PentaEnum:
+			bool isthermal;
+			this->parameters->FindParam(&isthermal,TransientIsthermalEnum);
+			if(isthermal){
+				bool isenthalpy;
+				this->parameters->FindParam(&isenthalpy,ThermalIsenthalpyEnum);
+				if(IsOnSurface()){
+					/*Here, we want to change the BC of the thermal model, keep
+					 * the temperatures as they are for the base of the penta and
+					 * use yearlytemperatures for the top*/
+					GetInputListOnVertices(&s[0],TemperatureEnum);
+					yearlytemperatures[0] = s[0];
+					yearlytemperatures[1] = s[1];
+					yearlytemperatures[2] = s[2];
+					this->inputs->AddInput(new PentaInput(TemperatureEnum,&yearlytemperatures[0],P1Enum));
+					if(isenthalpy){
+						/*Convert that to enthalpy for the enthalpy model*/
+						IssmDouble enthalpy[6];
+						GetInputListOnVertices(&enthalpy[0],EnthalpyEnum);
+						ThermalToEnthalpy(&enthalpy[3],yearlytemperatures[3],0.,0.);
+						ThermalToEnthalpy(&enthalpy[4],yearlytemperatures[4],0.,0.);
+						ThermalToEnthalpy(&enthalpy[5],yearlytemperatures[5],0.,0.);
+						this->inputs->AddInput(new PentaInput(EnthalpyEnum,&enthalpy[0],P1Enum));
+					}
+				}
+			}
+			this->inputs->AddInput(new PentaInput(SmbMassBalanceEnum,&smb[0],P1Enum));
+			this->inputs->AddInput(new PentaInput(TemperaturePDDEnum,&yearlytemperatures[0],P1Enum));
+			this->inputs->AddInput(new PentaInput(SmbAccumulationEnum,&accu[0],P1Enum));
+			this->inputs->AddInput(new PentaInput(SmbMeltEnum,&melt[0],P1Enum));
+			this->InputExtrude(TemperaturePDDEnum,-1);
+			this->InputExtrude(SmbMassBalanceEnum,-1);
+			this->InputExtrude(SmbAccumulationEnum,-1);
+			this->InputExtrude(SmbMeltEnum,-1);
+			break;
+		case TetraEnum:
+			if(IsOnSurface()){
+				GetInputListOnVertices(&s[0],TemperatureEnum);
+				yearlytemperatures[0] = s[0];
+				yearlytemperatures[1] = s[1];
+				yearlytemperatures[2] = s[2];
+				this->inputs->AddInput(new TetraInput(TemperatureEnum,&yearlytemperatures[0],P1Enum));
+			}
+			this->inputs->AddInput(new TetraInput(SmbMassBalanceEnum,&smb[0],P1Enum));
+			this->inputs->AddInput(new TetraInput(TemperaturePDDEnum,&yearlytemperatures[0],P1Enum));
+			this->InputExtrude(TemperaturePDDEnum,-1);
+			this->InputExtrude(SmbMassBalanceEnum,-1);
+			break;
+		default: _error_("Not implemented yet");
+	}
+
+	/*clean-up*/
+	delete gauss;
+	xDelete<IssmDouble>(monthlytemperatures);
+	xDelete<IssmDouble>(monthlyprec);
+	xDelete<IssmDouble>(smb);
+	xDelete<IssmDouble>(melt);
+	xDelete<IssmDouble>(accu);
+	xDelete<IssmDouble>(yearlytemperatures);
+	xDelete<IssmDouble>(s);
+	xDelete<IssmDouble>(s0t);
+	xDelete<IssmDouble>(s0p);
+	xDelete<IssmDouble>(t_ampl);
+	xDelete<IssmDouble>(p_ampl);
+	xDelete<IssmDouble>(smbcorr);
+	xDelete<IssmDouble>(melt_star);
+}
+/*}}}*/
 IssmDouble Element::PureIceEnthalpy(IssmDouble pressure){/*{{{*/
 	return this->matpar->PureIceEnthalpy(pressure);
@@ -2568,6 +2803,6 @@
 	/*Some intputs need to be computed, even if they are already in inputs, they might not be up to date!*/
 	switch(output_enum){
-		case ViscousHeatingEnum: this->ViscousHeatingCreateInput(); break;
-		case StressMaxPrincipalEnum: this->StressMaxPrincipalCreateInput(); break;
+	case ViscousHeatingEnum: this->ViscousHeatingCreateInput(); break;
+	case StressMaxPrincipalEnum: this->StressMaxPrincipalCreateInput(); break;
 		case StressTensorxxEnum:
 		case StressTensorxyEnum:
@@ -2582,5 +2817,5 @@
 		case StrainRateyzEnum:
 		case StrainRatezzEnum:
-		case StrainRateeffectiveEnum: this->ComputeStrainRate(); break;
+	  case StrainRateeffectiveEnum: this->ComputeStrainRate(); break;
 		case DeviatoricStressxxEnum:
 		case DeviatoricStressxyEnum:
@@ -3133,5 +3368,8 @@
 		}
 
-		#ifndef _HAVE_ADOLC_ //we want to avoid the round operation at all cost. Not differentiable.
+		#if defined(_HAVE_AD_)
+		/*we want to avoid the round operation at all cost. Not differentiable.*/
+		_error_("not implemented yet");
+		#else
 		dMass = sumMass + sumR + sumW - sumP - sumEC - initMass - sumMassAdd;
 		dMass = round(dMass * 100.0)/100.0;
Index: issm/trunk/src/c/classes/Elements/Element.h
===================================================================
--- issm/trunk/src/c/classes/Elements/Element.h	(revision 23389)
+++ issm/trunk/src/c/classes/Elements/Element.h	(revision 23394)
@@ -1,7 +1,7 @@
 /*!\file:  Element.h
  * \brief abstract class for Element object
- * This class is a place holder for the Tria and the Penta elements. 
+ * This class is a place holder for the Tria and the Penta elements.
  * It is derived from Element, so DataSets can contain them.
- */ 
+ */
 
 #ifndef _ELEMENT_H_
@@ -50,5 +50,5 @@
 		int  element_type;
 
-	public: 
+	public:
 		/*Constructors/Destructores*/
 		Element();
@@ -68,4 +68,5 @@
 		void               Delta18oParameterization(void);
 		void               Delta18opdParameterization(void);
+		void               SmbGradCompParameterization(void);
 		IssmDouble         Divergence(void);
 		void               dViscositydBFS(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
@@ -130,14 +131,14 @@
 		void               InputUpdateFromConstant(int constant, int name);
 		void               InputUpdateFromConstant(bool constant, int name);
-		bool               IsFloating(); 
+		bool               IsFloating();
 		bool               IsIceInElement();
 		bool               IsLandInElement();
 		bool               IsWaterInElement();
-		void               LinearFloatingiceMeltingRate(); 
-		void               SpatialLinearFloatingiceMeltingRate(); 
-		void               MantlePlumeGeothermalFlux(); 
+		void               LinearFloatingiceMeltingRate();
+		void               SpatialLinearFloatingiceMeltingRate();
+		void               MantlePlumeGeothermalFlux();
 		void               MarshallElement(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction,int numanalyses);
 		void               MigrateGroundingLine(IssmDouble* sheet_ungrounding);
-		void               MismipFloatingiceMeltingRate(); 
+		void               MismipFloatingiceMeltingRate();
 		void               MungsmtpParameterization(void);
 		ElementMatrix*     NewElementMatrix(int approximation_enum=NoneApproximationEnum);
@@ -145,4 +146,5 @@
 		ElementVector*     NewElementVector(int approximation_enum=NoneApproximationEnum);
 		void               PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm,bool ismungsm,bool issetpddfac);
+		void               PositiveDegreeDaySicopolis(bool isfirnwarming);
 		IssmDouble         PureIceEnthalpy(IssmDouble pressure);
 		void               ResultInterpolation(int* pinterpolation,int*nodesperelement,int* parray_size, int output_enum);
@@ -240,5 +242,5 @@
 		virtual bool       IsFaceOnBoundary(void)=0;
 		virtual bool       IsIcefront(void)=0;
-		virtual bool       IsNodeOnShelfFromFlags(IssmDouble* flags)=0; 
+		virtual bool       IsNodeOnShelfFromFlags(IssmDouble* flags)=0;
 		virtual bool       IsOnBase()=0;
 		virtual bool       IsOnSurface()=0;
@@ -330,5 +332,5 @@
 		virtual IssmDouble    OceanAverage(IssmDouble* Sg)=0;
 		virtual IssmDouble    OceanArea(void)=0;
-		virtual void          SealevelriseMomentOfInertia(IssmDouble* dI_list,IssmDouble* Sg_old,IssmDouble eartharea)=0; 
+		virtual void          SealevelriseMomentOfInertia(IssmDouble* dI_list,IssmDouble* Sg_old,IssmDouble eartharea)=0;
 		virtual void          SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea)=0;
 		virtual void          SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea)=0;
Index: issm/trunk/src/c/classes/ExternalResults/GenericExternalResult.h
===================================================================
--- issm/trunk/src/c/classes/ExternalResults/GenericExternalResult.h	(revision 23389)
+++ issm/trunk/src/c/classes/ExternalResults/GenericExternalResult.h	(revision 23394)
@@ -622,5 +622,5 @@
 
 	/*Specific instantiations for IssmDouble*: */
-#if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_)  //We hook off this specific specialization when not running ADOLC, otherwise we get a redeclaration with the next specialization. 
+#if defined(_HAVE_AD_) && !defined(_WRAPPERS_)  //We hook off this specific specialization when not running ADOLC, otherwise we get a redeclaration with the next specialization. 
 template <> inline GenericExternalResult<IssmDouble*>::~GenericExternalResult(){ /*{{{*/
 	xDelete<char>(result_name);
@@ -709,5 +709,5 @@
 		return new GenericExternalResult<Vector<IssmPDouble>*>(this->id,StringToEnumx(this->result_name),this->value,this->step,this->time);
 	} /*}}}*/
-#if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_)  //We hook off this specific specialization when not running ADOLC, otherwise we get a redeclaration with the next specialization. 
+#if defined(_HAVE_AD_) && !defined(_WRAPPERS_)  //We hook off this specific specialization when not running ADOLC, otherwise we get a redeclaration with the next specialization. 
 	template <> inline void GenericExternalResult<Vector<IssmPDouble>*>::WriteData(FILE* fid,bool io_gather){ /*{{{*/
 
Index: issm/trunk/src/c/classes/FemModel.cpp
===================================================================
--- issm/trunk/src/c/classes/FemModel.cpp	(revision 23389)
+++ issm/trunk/src/c/classes/FemModel.cpp	(revision 23394)
@@ -17,4 +17,9 @@
 #include "../shared/Enum/Enum.h"
 #include "../analyses/analyses.h"
+
+#if _HAVE_CODIPACK_
+#include <sstream> // for output of the CoDiPack tape
+extern CoDi_global codi_global;
+#endif
 
 /*module includes: {{{*/
@@ -84,11 +89,11 @@
 	this->parameters->FindParam(&amr_frequency,TransientAmrFrequencyEnum);
 	this->parameters->FindParam(&amr_frequency,TransientAmrFrequencyEnum);
-	#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_)
+	#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
 	this->amr = NULL;
 	#endif
-	#if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_)
+	#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
 	this->amrbamg = NULL;
 	#endif
-	#if !defined(_HAVE_ADOLC_)
+	#if !defined(_HAVE_AD_)
 	if(amr_frequency && solution_type==TransientSolutionEnum){
 		/*Verifications. AMR supports SSA, P1 and horizontal 2D domain*/
@@ -147,8 +152,8 @@
 	profiler->Stop(MPROCESSOR);
 
-	#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_)
+	#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
 	this->amr = NULL;
 	#endif
-	#if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_)
+	#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
 	this->amrbamg = NULL;
 	#endif
@@ -184,9 +189,9 @@
 	if(results)delete results;
 
-	#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_)
+	#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
 	if(amr)delete amr;
 	#endif
 
-	#if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_)
+	#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
 	if(amrbamg)delete amrbamg;
 	#endif
@@ -254,8 +259,12 @@
 	/*Before we delete the profiler, report statistics for this run: */
 	profiler->Stop(TOTAL);  //final tagging
+
 	_printf0_("\n");
-	_printf0_("   "<<setw(40)<<left<<"FemModel initialization elapsed time:"<<profiler->TotalTime(MPROCESSOR) << "\n");
-	_printf0_("   "<<setw(40)<<left<<"Core solution elapsed time:"<<profiler->TotalTime(CORE) << "\n");
-	_printf0_("   "<<setw(40)<<left<<"Solver elapsed time:"<<profiler->TotalTime(SOLVER) << "\n");
+	_printf0_("   "<<setw(40)<<left<<"FemModel initialization elapsed time:"<<setw(7)<<profiler->TotalTime(MPROCESSOR) << "\n");
+	/*Total times*/
+	_printf0_("   "<<setw(40)<<left<<"Total Core solution elapsed time:"<<setw(7)<<profiler->TotalTime(CORE) << "\n");
+
+	/*Linear solver only*/
+	_printf0_("   "<<setw(40)<<left<<"Linear solver elapsed time:"<<setw(7)<<profiler->TotalTime(SOLVER) << " ("<<setprecision(2)<<profiler->TotalTime(SOLVER)/profiler->TotalTime(CORE)*100.<<"%)\n");
 	_printf0_("\n");
 	_printf0_("   Total elapsed time: "
@@ -319,8 +328,8 @@
 
 	/*AMR, no copy for now*/
-	#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_)
+	#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
 	this->amr = NULL;
 	#endif
-	#if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_)
+	#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
 	this->amrbamg = NULL;
 	#endif
@@ -853,8 +862,23 @@
 		solution_memory=profiler->Memory(CORE);
 
-		_printf0_("Core solution elapsed time    : " << solution_time   << " Seconds\n");
-		_printf0_("Core solution number of flops : " << solution_flops  << " Flops\n");
-		_printf0_("Core solution memory used     : " << solution_memory << " Bytes\n");
-
+		_printf0_("\nCore solution profiling\n");
+		_printf0_("   elapsed time    : " << solution_time   << " Seconds\n");
+		_printf0_("   number of flops : " << solution_flops  << " Flops\n");
+		_printf0_("   memory used     : " << solution_memory << " Bytes\n");
+
+		/*Individual cores*/
+		_printf0_("Individual core profiling\n");
+		if(profiler->Used(THERMALCORE)) _printf0_("   "<<setw(40)<<left<<"Thermal core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(THERMALCORE) << " sec\n");
+		if(profiler->Used(HYDROLOGYCORE)) _printf0_("   "<<setw(40)<<left<<"Hydrology core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(HYDROLOGYCORE) << " sec\n");
+		if(profiler->Used(STRESSBALANCECORE)) _printf0_("   "<<setw(40)<<left<<"Stress balance core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(STRESSBALANCECORE) << " sec\n");
+		if(profiler->Used(DAMAGECORE)) _printf0_("   "<<setw(40)<<left<<"Damage core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(DAMAGECORE) << " sec\n");
+		if(profiler->Used(MOVINGFRONTCORE)) _printf0_("   "<<setw(40)<<left<<"Moving front core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(MOVINGFRONTCORE) << " sec\n");
+		if(profiler->Used(MASSTRANSPORTCORE)) _printf0_("   "<<setw(40)<<left<<"Mass transport core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(MASSTRANSPORTCORE) << " sec\n");
+		if(profiler->Used(SMBCORE)) _printf0_("   "<<setw(40)<<left<<"SMB core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(SMBCORE) << " sec\n");
+		if(profiler->Used(GROUNDINGLINECORE)) _printf0_("   "<<setw(40)<<left<<"Groundingline migration core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(GROUNDINGLINECORE) << " sec\n");
+		if(profiler->Used(GIACORE)) _printf0_("   "<<setw(40)<<left<<"GIA core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(GIACORE) << " sec\n");
+		if(profiler->Used(ESACORE)) _printf0_("   "<<setw(40)<<left<<"ESA core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(ESACORE) << " sec\n");
+		if(profiler->Used(SLRCORE)) _printf0_("   "<<setw(40)<<left<<"SLR core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(SLRCORE) << " sec\n");
+		
 		/*Add to results: */
 		results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingSolutionTimeEnum,  solution_time));
@@ -862,13 +886,15 @@
 		results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingCurrentFlopsEnum, solution_flops));
 
-		#ifdef _HAVE_ADOLC_
-		solution_time=profiler->TotalTime(ADCORE);
-		solution_flops=profiler->TotalFlops(ADCORE);
-		solution_memory=profiler->Memory(ADCORE);
-
-		_printf0_("AD Solution elapsed time    : " << solution_time   << " Seconds\n");
-		_printf0_("AD Solution number of flops : " << solution_flops  << " Flops\n");
-		_printf0_("AD Solution memory used     : " << solution_memory << " Bytes\n");
+		#ifdef _HAVE_AD_
+		solution_time   = profiler->TotalTime(ADCORE);
+		solution_flops  = profiler->TotalFlops(ADCORE);
+		solution_memory = profiler->Memory(ADCORE);
+
+		_printf0_("AD profiling\n");
+		_printf0_("   elapsed time    : " << solution_time   << " Seconds\n");
+		_printf0_("   number of flops : " << solution_flops  << " Flops\n");
+		_printf0_("   memory used     : " << solution_memory << " Bytes\n");
 		#endif
+		_printf0_("\n");
 
 	}
@@ -1824,9 +1850,13 @@
 
 	if(isautodiff){
-		#ifdef _HAVE_ADOLC_
+		#ifdef _HAVE_AD_
 		parameters->FindParam(&num_dependents,AutodiffNumDependentsEnum);
 		parameters->FindParam(&dependent_objects,AutodiffDependentObjectsEnum);
 		if(num_dependents){
 			dependents=xNew<IssmPDouble>(num_dependents);
+
+			#if defined(_HAVE_CODIPACK_)
+			auto& tape_codi = IssmDouble::getGlobalTape();
+			#endif
 
 			/*Go through our dependent variables, and compute the response:*/
@@ -1835,5 +1865,11 @@
 				dep->Responsex(&output_value,this);
 				if (my_rank==0) {
-					output_value>>=dependents[i];
+					#if defined(_HAVE_CODIPACK_)
+						tape_codi.registerOutput(output_value);
+						dependents[i] = output_value.getValue();
+						codi_global.output_indices.push_back(output_value.getGradientData());
+					#else
+						output_value>>=dependents[i];
+					#endif
 				}
 			}
@@ -2509,5 +2545,5 @@
 
 /*AMR*/
-#if !defined(_HAVE_ADOLC_)
+#ifndef _HAVE_AD_
 void FemModel::ReMesh(void){/*{{{*/
 
@@ -2528,9 +2564,9 @@
 	this->parameters->FindParam(&amrtype,AmrTypeEnum);
 	switch(amrtype){
-		#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_)
+		#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
 		case AmrNeopzEnum: this->ReMeshNeopz(&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist); break;
 								 #endif
 
-		#if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_)
+		#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
 		case AmrBamgEnum: this->ReMeshBamg(&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist); break;
 		#endif
@@ -4884,5 +4920,5 @@
 #endif
 
-#if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_)
+#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
 void FemModel::ReMeshBamg(int* pnewnumberofvertices,int* pnewnumberofelements,IssmDouble** pnewx,IssmDouble** pnewy,IssmDouble** pnewz,int** pnewelementslist){/*{{{*/
 
@@ -5210,5 +5246,5 @@
 #endif
 
-#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_)
+#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
 void FemModel::ReMeshNeopz(int* pnewnumberofvertices,int* pnewnumberofelements,IssmDouble** pnewx,IssmDouble** pnewy,IssmDouble** pnewz,int** pnewelementslist){/*{{{*/
 
Index: issm/trunk/src/c/classes/FemModel.h
===================================================================
--- issm/trunk/src/c/classes/FemModel.h	(revision 23389)
+++ issm/trunk/src/c/classes/FemModel.h	(revision 23394)
@@ -20,8 +20,8 @@
 class Profiler;
 class Elements;
-#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_)
+#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
 #include "./AdaptiveMeshRefinement.h"
 #endif
-#if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_)
+#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
 #include "./AmrBamg.h"
 #endif
@@ -51,9 +51,9 @@
 
 		//FIXME: do we want only one class and have virtual functions? or keep 2 classes, at least rename AdaptiveMeshRefinement -> AmrNeopz
-		#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_)
+		#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
 		AdaptiveMeshRefinement *amr;		  //adaptive mesh refinement object. It keeps coarse mesh and execute refinement process
 		#endif
 
-		#if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_)
+		#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
 		AmrBamg *amrbamg; //adaptive mesh refinement object. It keeps coarse mesh and execute refinement process
 		#endif
@@ -164,5 +164,5 @@
 
 		/*AMR*/
-		#if !defined(_HAVE_ADOLC_)
+		#if !defined(_HAVE_AD_)
 		void ReMesh(void);
 		void BedrockFromMismipPlus(void);
@@ -191,5 +191,5 @@
 		#endif
 
-		#if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_)
+		#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
 		void ReMeshBamg(int* pnewnumberofvertices,int* pnewnumberofelements,IssmDouble** pnewx,IssmDouble** pnewy,IssmDouble** pnewz,int** pnewelementslist);
 		void InitializeAdaptiveRefinementBamg(void);
@@ -199,5 +199,5 @@
 		#endif
 
-		#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_)
+		#if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
 		void ReMeshNeopz(int* pnewnumberofvertices,int* pnewnumberofelements,IssmDouble** pnewx,IssmDouble** pnewy,IssmDouble** pnewz,int** pnewelementslist);
 		void InitializeAdaptiveRefinementNeopz(void);
Index: issm/trunk/src/c/classes/IoModel.cpp
===================================================================
--- issm/trunk/src/c/classes/IoModel.cpp	(revision 23389)
+++ issm/trunk/src/c/classes/IoModel.cpp	(revision 23394)
@@ -27,4 +27,9 @@
 #include "../shared/io/io.h"
 #include "../shared/shared.h"
+
+#ifdef _HAVE_CODIPACK_
+extern CoDi_global codi_global;
+#include <sstream> // for output of the CoDiPack tape
+#endif
 
 /*IoConstant class and methods*/
@@ -431,5 +436,6 @@
 	if(trace || (autodiff && !iscontrol)){
 
-		#ifdef _HAVE_ADOLC_
+		#ifdef _HAVE_AD_
+		// FIXME codi here we should be able to execute codi version as normal
 		this->FetchData(&num_independent_objects,"md.autodiff.num_independent_objects");
 		if(num_independent_objects){
@@ -460,5 +466,5 @@
 		#else
 		/*if we asked for AD computations, we have a problem!: */
-		_error_("Cannot carry out AD mode computations without support of ADOLC compiled in!");
+		_error_("Cannot carry out AD mode computations without support of ADOLC or CoDiPack compiled in!");
 		#endif
 	}
@@ -1702,5 +1708,5 @@
 	if(X) Xcount=*pXcount;
 
-	#ifdef _HAVE_ADOLC_ //cannot come here unless you are running AD mode, from DeclaredIndependents:
+	#ifdef _HAVE_AD_ //cannot come here unless you are running AD mode, from DeclaredIndependents:
 
 	/*output: */
@@ -1719,10 +1725,22 @@
 		/*Now, before we even broadcast this to other nodes, declare the scalar  as an independent variable!. If we 
 		 *have been supplied an X vector, use it instead of what we just read: */
-		if(X){
-			scalar<<=X[Xcount];
-		}
-		else{
-			scalar<<=pscalar;
-		}
+		#if defined(_HAVE_CODIPACK_)
+			// FIXME codi here we just assign instead of using "operator <<="
+			if(X){
+				scalar=X[Xcount];
+			} else {
+				scalar=pscalar;
+			}
+			auto& tape_codi = IssmDouble::getGlobalTape();
+			tape_codi.registerInput(scalar);
+			codi_global.input_indices.push_back(scalar.getGradientData());
+		#else
+			if(X){
+				scalar<<=X[Xcount];
+			}
+			else{
+				scalar<<=pscalar;
+			}
+		#endif
 	}
 
@@ -1744,5 +1762,5 @@
 	if(X) Xcount=*pXcount;
 
-	#ifdef _HAVE_ADOLC_ //cannot come here unless you are running AD mode, from DeclaredIndependents:
+	#ifdef _HAVE_AD_ //cannot come here unless you are running AD mode, from DeclaredIndependents:
 
 	/*Intermediaries*/
@@ -1785,10 +1803,29 @@
 			/*Now, before we even broadcast this to other nodes, declare the whole matrix as a independent variable!
 			  If we have been supplied an X vector, use it instead of what we just read: */
-			if(X){
-				for(int i=0;i<M*N;i++) matrix[i]<<=X[Xcount+i];  /*<<= ADOLC overloaded operator to declare independent*/
-			}
-			else{
-				for(int i=0;i<M*N;i++) matrix[i]<<=buffer[i];
-			}
+			#if defined(_HAVE_CODIPACK_)
+				// FIXME codi here we just assign instead of using "operator <<="
+				auto& tape_codi = IssmDouble::getGlobalTape();
+				if(X){
+					for (int i=0;i<M*N;i++) {
+						matrix[i]=X[Xcount+i];
+						tape_codi.registerInput(matrix[i]);
+						codi_global.input_indices.push_back(matrix[i].getGradientData());
+					}
+				}
+				else{
+					for (int i=0;i<M*N;i++) {
+						matrix[i]=buffer[i];
+						tape_codi.registerInput(matrix[i]);
+						codi_global.input_indices.push_back(matrix[i].getGradientData());
+					}
+				}
+			#else /*ADOLC*/
+				if(X){
+					for(int i=0;i<M*N;i++) matrix[i]<<=X[Xcount+i];  /*<<= ADOLC overloaded operator to declare independent*/
+				}
+				else{
+					for(int i=0;i<M*N;i++) matrix[i]<<=buffer[i];
+				}
+			#endif
 		}
 		ISSM_MPI_Bcast(matrix,M*N,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 
@@ -1798,4 +1835,6 @@
 	else _error_("cannot declare the independent variable \"" << data_name <<  "\" if it's empty!");
 
+	// FIXME codi is that at all relevant to CoDiPack or can we simply assume the same?
+	
 	/*Add to data as independent*/
 	this->AddDataIndependent(new IoData(matrix,code,layout,M,N,data_name));
@@ -2472,5 +2511,7 @@
 	/*recover my_rank:*/
 	my_rank=IssmComm::GetRank();
-	_assert_(strncmp(data_name,mddot,3)==0);
+	if(strncmp(data_name,mddot,3)!=0){
+		_error_("Cannot fetch \""<<data_name<<"\" does not start with \""<<mddot<<"\"");
+	}
 
 	/*Go find in the binary file, the position of the data we want to fetch: */
@@ -2562,5 +2603,6 @@
 
 	if(trace || (autodiff && !iscontrol)){
-		#ifdef _HAVE_ADOLC_
+
+		#if defined(_HAVE_ADOLC_)
 		/*Retrieve parameters: */
 		this->FetchData(&keep,"md.autodiff.keep");
@@ -2579,7 +2621,35 @@
 		int skipFileDeletion=1;
 		trace_on(my_rank,keepTaylors,reCast<size_t>(obufsize),reCast<size_t>(lbufsize),reCast<size_t>(cbufsize),reCast<size_t>(tbufsize),skipFileDeletion);
+
+		#elif defined(_HAVE_CODIPACK_)
+		//fprintf(stderr, "*** Codipack IoModel::StartTrace\n");
+		/*
+		 * FIXME codi
+		 * - ADOL-C variant uses fine grained tracing with various arguments
+		 * - ADOL-C variant sets a garbage collection parameter for its tape
+		 * -> These parameters are not read for the CoDiPack ISSM version!
+		 */
+		auto& tape_codi = IssmDouble::getGlobalTape();
+		tape_codi.setActive();
+		#if _AD_TAPE_ALLOC_
+		//alloc_profiler.Tag(StartInit, true);
+		IssmDouble x_t(1.0), y_t(1.0);
+		tape_codi.registerInput(y_t);
+		int codi_allocn = 0;
+		this->FetchData(&codi_allocn,"md.autodiff.tapeAlloc");
+		for(int i = 0;i < codi_allocn;++i) {
+			x_t = y_t * y_t;
+		}
+		/*
+		std::stringstream out_s;
+		IssmDouble::getGlobalTape().printStatistics(out_s);
+		_printf0_("StartTrace::Tape Statistics	   : TapeAlloc count=[" << codi_allocn << "]\n" << out_s.str());
+		*/
+		tape_codi.reset();
+		//alloc_profiler.Tag(FinishInit, true);
 		#endif
-	}
-
-}
-/*}}}*/
+		#endif
+	}
+
+}
+/*}}}*/
Index: issm/trunk/src/c/classes/Materials/Matpar.cpp
===================================================================
--- issm/trunk/src/c/classes/Materials/Matpar.cpp	(revision 23389)
+++ issm/trunk/src/c/classes/Materials/Matpar.cpp	(revision 23394)
@@ -107,9 +107,13 @@
 					iomodel->FindConstant(&this->rlapslgm,"md.smb.rlapslgm");
 					break;
+				case SMBpddSicopolisEnum:
+					iomodel->FindConstant(&this->desfac,"md.smb.desfac");
+					iomodel->FindConstant(&this->rlaps,"md.smb.rlaps");
+					break;
 				case SMBd18opddEnum:
 					iomodel->FindConstant(&this->desfac,"md.smb.desfac");
 					iomodel->FindConstant(&this->rlaps,"md.smb.rlaps");
 					iomodel->FindConstant(&this->rlapslgm,"md.smb.rlapslgm");
-					iomodel->FindConstant(&this->dpermil,"md.smb.dpermil");					
+					iomodel->FindConstant(&this->dpermil,"md.smb.dpermil");
 				case SMBgradientsEnum:
 					/*Nothing to add*/
@@ -125,4 +129,7 @@
 					break;
 				case SMBmeltcomponentsEnum:
+					/*Nothing to add*/
+					break;
+				case SMBgradientscomponentsEnum:
 					/*Nothing to add*/
 					break;
@@ -170,9 +177,9 @@
 			break;
 		case MaterialsEnum:
-			//we have several types of materials. Retrieve this info first: 
+			//we have several types of materials. Retrieve this info first:
 			iomodel->FetchData(&nature,&nnat,&dummy,"md.materials.nature");
 
-			//go through list of materials, and create constant parameters accordingly: 
-			for(int i=0;i<nnat;i++){ 
+			//go through list of materials, and create constant parameters accordingly:
+			for(int i=0;i<nnat;i++){
 				switch(IoCodeToEnumMaterials(nature[i])){ //{{{
 					case MatlithoEnum:
@@ -211,9 +218,13 @@
 								iomodel->FindConstant(&this->rlapslgm,"md.smb.rlapslgm");
 								break;
+							case SMBpddSicopolisEnum:
+								iomodel->FindConstant(&this->desfac,"md.smb.desfac");
+								iomodel->FindConstant(&this->rlaps,"md.smb.rlaps");
+								break;
 							case SMBd18opddEnum:
 								iomodel->FindConstant(&this->desfac,"md.smb.desfac");
 								iomodel->FindConstant(&this->rlaps,"md.smb.rlaps");
 								iomodel->FindConstant(&this->rlapslgm,"md.smb.rlapslgm");
-								iomodel->FindConstant(&this->dpermil,"md.smb.dpermil");					
+								iomodel->FindConstant(&this->dpermil,"md.smb.dpermil");
 							case SMBgradientsEnum:
 								/*Nothing to add*/
@@ -233,5 +244,5 @@
 							default:
 								_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
-						} 
+						}
 						if(hydrology_model==HydrologydcEnum){
 							iomodel->FindConstant(&this->sediment_compressibility,"md.hydrology.sediment_compressibility");
@@ -350,5 +361,5 @@
 
 	this->Echo();
-}		
+}
 /*}}}*/
 void Matpar::Echo(void){/*{{{*/
@@ -381,16 +392,16 @@
 	_printf_("   sediment_porosity: " << sediment_porosity << "\n");
 	_printf_("   sediment_thickness: " << sediment_thickness << "\n");
-	_printf_("   water_compressibility: " << water_compressibility << "\n");	
-	_printf_("   epl_compressibility: " << epl_compressibility << "\n");	
-	_printf_("   epl_porosity: " << epl_porosity << "\n");	
-	_printf_("   epl_init_thickness: " << epl_init_thickness << "\n");	
-	_printf_("   epl_colapse_thickness: " << epl_colapse_thickness << "\n");	
-	_printf_("   epl_max_thickness: " << epl_max_thickness << "\n");	
-	_printf_("   epl_conductivity: " << epl_conductivity << "\n");	
-	_printf_("   lithosphere_shear_modulus: " << lithosphere_shear_modulus << "\n");	
-	_printf_("   lithosphere_density: " << lithosphere_density << "\n");	
-	_printf_("   mantle_shear_modulus: " << mantle_shear_modulus << "\n");	
-	_printf_("   mantle_density: " << mantle_density << "\n");	
-	_printf_("   earth_density: " << earth_density << "\n");	
+	_printf_("   water_compressibility: " << water_compressibility << "\n");
+	_printf_("   epl_compressibility: " << epl_compressibility << "\n");
+	_printf_("   epl_porosity: " << epl_porosity << "\n");
+	_printf_("   epl_init_thickness: " << epl_init_thickness << "\n");
+	_printf_("   epl_colapse_thickness: " << epl_colapse_thickness << "\n");
+	_printf_("   epl_max_thickness: " << epl_max_thickness << "\n");
+	_printf_("   epl_conductivity: " << epl_conductivity << "\n");
+	_printf_("   lithosphere_shear_modulus: " << lithosphere_shear_modulus << "\n");
+	_printf_("   lithosphere_density: " << lithosphere_density << "\n");
+	_printf_("   mantle_shear_modulus: " << mantle_shear_modulus << "\n");
+	_printf_("   mantle_density: " << mantle_density << "\n");
+	_printf_("   earth_density: " << earth_density << "\n");
 	return;
 }
@@ -512,5 +523,5 @@
 			this->dpermil=constant;
 			break;
-		default: 
+		default:
 			break;
 	}
Index: issm/trunk/src/c/classes/Numberedcostfunction.cpp
===================================================================
--- issm/trunk/src/c/classes/Numberedcostfunction.cpp	(revision 23389)
+++ issm/trunk/src/c/classes/Numberedcostfunction.cpp	(revision 23394)
@@ -149,6 +149,8 @@
 				 _error_("not supported");
 		 }
+		 _printf0_("#"<<i+1<<": "<<value<<" ");
 		 value_sum += value;
  }
+	 _printf0_("\n");
 
 	 /*done:*/
Index: issm/trunk/src/c/classes/Options/GenericOption.h
===================================================================
--- issm/trunk/src/c/classes/Options/GenericOption.h	(revision 23389)
+++ issm/trunk/src/c/classes/Options/GenericOption.h	(revision 23394)
@@ -102,5 +102,5 @@
 };
 
-#if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_) 
+#if defined(_HAVE_AD_) && !defined(_WRAPPERS_) 
 /*We hook off this specific specialization when not running ADOLC, otherwise we get a redeclaration with the next specialization*/
 template <> inline void GenericOption<IssmPDouble*>::Get(IssmPDouble** pvalue){ /*{{{*/
Index: issm/trunk/src/c/classes/Params/Parameters.cpp
===================================================================
--- issm/trunk/src/c/classes/Params/Parameters.cpp	(revision 23389)
+++ issm/trunk/src/c/classes/Params/Parameters.cpp	(revision 23394)
@@ -92,5 +92,5 @@
 }
 /*}}}*/
-void Parameters::DeepEcho(void){/*{{{*/	
+void Parameters::DeepEcho(void){/*{{{*/
 	for(int i=0;i<NUMPARAMS;i++) {
 		if(this->params[i]) this->params[i]->DeepEcho();
@@ -99,5 +99,5 @@
 }
 /*}}}*/
-void Parameters::Echo(void){/*{{{*/	
+void Parameters::Echo(void){/*{{{*/
 	for(int i=0;i<NUMPARAMS;i++) {
 		if(this->params[i]) this->params[i]->Echo();
@@ -139,5 +139,5 @@
 
 			/*Recover enum of object first: */
-			MARSHALLING(obj_enum); 
+			MARSHALLING(obj_enum);
 
 			if(obj_enum==DoubleParamEnum){
@@ -200,5 +200,5 @@
 				fileparam->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
 				delete fileparam;
-				/* No need to add this object, the pointer is not valid             
+				/* No need to add this object, the pointer is not valid
 					The FemModel should reset all FileParams in the restart function */
 			}
@@ -426,4 +426,40 @@
 }
 /*}}}*/
+void Parameters::FindParamAndMakePassive(IssmPDouble* pscalar,int param_enum){ _assert_(this);/*{{{*/
+	_assert_(param_enum>ParametersSTARTEnum);
+	_assert_(param_enum<ParametersENDEnum);
+
+	/*Get "active" parameter*/
+	IssmDouble intermediary;
+	int index = param_enum - ParametersSTARTEnum -1;
+	if(!this->params[index]) _error_("Parameter " << EnumToStringx(param_enum) <<" not set");
+	this->params[index]->GetParameterValue(&intermediary);
+
+	/*cast to "passive"*/
+	*pscalar=reCast<IssmPDouble>(intermediary);
+}
+/*}}}*/
+void Parameters::FindParamAndMakePassive(IssmPDouble** pvec,int* pM, int param_enum){ _assert_(this);/*{{{*/
+
+	_assert_(param_enum>ParametersSTARTEnum);
+	_assert_(param_enum<ParametersENDEnum);
+
+	int index = param_enum - ParametersSTARTEnum -1;
+
+	/*Output*/
+	int         n;
+	IssmDouble* vector = NULL;
+
+	if(!this->params[index]) _error_("Parameter " << EnumToStringx(param_enum) <<" not set");
+	this->params[index]->GetParameterValue(&vector,&n);
+
+	/*Make output passive*/
+	IssmPDouble* output = xNew<IssmPDouble>(n);
+	for(int i=0;i<n;i++) output[i] = reCast<IssmPDouble>(vector[i]);
+
+	/*assign output pointers*/
+	if(pvec) *pvec = output;
+	if(pM)   *pM   = n;
+}/*}}}*/
 void Parameters::FindParamInDataset(IssmDouble** pIssmDoublearray,int* pM,int* pN,int dataset_type,int enum_type){/*{{{*/
 	_assert_(this);
@@ -613,5 +649,5 @@
 char* OptionsFromAnalysis(char** pouttoolkit,Parameters* parameters,int analysis_type){ /*{{{*/
 
-	/* figure out ISSM options for current analysis, return a string. */ 
+	/* figure out ISSM options for current analysis, return a string. */
 
 	/*output: */
@@ -631,6 +667,6 @@
 
 	parameters->FindParam(&strings,&numanalyses,ToolkitsOptionsStringsEnum);
-	parameters->FindParam(&toolkits,&dummy,ToolkitsTypesEnum); _assert_(dummy==numanalyses); 
-	parameters->FindParam(&analyses,&dummy,ToolkitsOptionsAnalysesEnum); _assert_(dummy==numanalyses); 
+	parameters->FindParam(&toolkits,&dummy,ToolkitsTypesEnum); _assert_(dummy==numanalyses);
+	parameters->FindParam(&analyses,&dummy,ToolkitsOptionsAnalysesEnum); _assert_(dummy==numanalyses);
 
 	if(numanalyses==0)return NULL; //we did not find petsc options, don't bother.
@@ -674,14 +710,14 @@
 	xDelete<int>(analyses);
 	return outstring;
-} 
+}
 /*}}}*/
 void ToolkitsOptionsFromAnalysis(Parameters* parameters,int analysis_type){ /*{{{*/
 
 	/*!\file:  ToolkitsOptionsFromAnalysis.cpp
-	 * \brief: for each analysis, setup the issmoptions string. 
-	 * This is mainly for the case where we run our toolkits using petsc. In this case, we need to 
-	 * plug our toolkits options directly into the petsc options database. This is the case for each analysis type 
+	 * \brief: for each analysis, setup the issmoptions string.
+	 * This is mainly for the case where we run our toolkits using petsc. In this case, we need to
+	 * plug our toolkits options directly into the petsc options database. This is the case for each analysis type
 	 * and parameters
-	 */ 
+	 */
 
 	char* options = NULL;
@@ -695,5 +731,5 @@
 
 	#ifdef _HAVE_PETSC_
-		/*In case we are using PETSC, we do not rely on issmoptions. Instead, we dump issmoptions into the Petsc 
+		/*In case we are using PETSC, we do not rely on issmoptions. Instead, we dump issmoptions into the Petsc
 		 * options database: */
 		#if (_PETSC_MINOR_>=7)
@@ -717,20 +753,2 @@
 }
 /*}}}*/
-
-/*Specific case with ADOL-C, we might need to get double params for m1qn3*/
-#if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_) 
-void Parameters::FindParamAndMakePassive(double* pscalar,int param_enum){ _assert_(this);/*{{{*/
-	_assert_(param_enum>ParametersSTARTEnum);
-	_assert_(param_enum<ParametersENDEnum);
-
-	/*Get "active" parameter*/
-	IssmDouble intermediary;
-	int index = param_enum - ParametersSTARTEnum -1;
-	if(!this->params[index]) _error_("Parameter " << EnumToStringx(param_enum) <<" not set");
-	this->params[index]->GetParameterValue(&intermediary);
-
-	/*cast to "passive"*/
-	*pscalar=reCast<double>(intermediary);
-}
-/*}}}*/
-#endif
Index: issm/trunk/src/c/classes/Params/Parameters.h
===================================================================
--- issm/trunk/src/c/classes/Params/Parameters.h	(revision 23389)
+++ issm/trunk/src/c/classes/Params/Parameters.h	(revision 23394)
@@ -52,4 +52,6 @@
 		void  FindParam(FILE** pfid,int enum_type);
 		void  FindParam(DataSet** pdataset, int enum_type);
+		void  FindParamAndMakePassive(IssmPDouble* pscalar, int enum_type);
+		void  FindParamAndMakePassive(IssmPDouble** pvec,int* pM,int enum_type);
 		void  FindParamInDataset(IssmDouble** pIssmDoublearray,int* pM,int* pN,int dataset_type,int enum_type);
 
@@ -70,9 +72,4 @@
 		Param* FindParamObject(int enum_type);
 
-		/*Specific instantiations for IssmDouble*: */
-		#if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_) 
-		void  FindParamAndMakePassive(double* pscalar, int enum_type);
-		#endif
-
 };
 
Index: issm/trunk/src/c/classes/Profiler.cpp
===================================================================
--- issm/trunk/src/c/classes/Profiler.cpp	(revision 23389)
+++ issm/trunk/src/c/classes/Profiler.cpp	(revision 23394)
@@ -15,5 +15,5 @@
 /*Profiler constructors and destructors:*/
 Profiler::Profiler(){/*{{{*/
-	for(int i=0;i<MAXIMUMSIZE;i++){
+	for(int i=0;i<MAXPROFSIZE;i++){
 		this->time[i]          = 0.;
 		this->time_start[i]    = 0.;
@@ -23,4 +23,5 @@
 		this->memory_start[i]  = 0.;
 		this->running[i]       = false;
+		this->used[i]          = false;
 	}
 } /*}}}*/
@@ -32,5 +33,5 @@
 	Profiler* output=new Profiler();
 
-	for(int i=0;i<MAXIMUMSIZE;i++){
+	for(int i=0;i<MAXPROFSIZE;i++){
 		output->time[i]  =this->time[i];
 		output->flops[i] =this->flops[i];
@@ -49,5 +50,5 @@
 
 	_printf_("Profiler:\n");
-	for(int i=0;i<MAXIMUMSIZE;i++){
+	for(int i=0;i<MAXPROFSIZE;i++){
 		_printf_("    Tag "<<i<<":\n");
 		_printf_("       flops:   "<<this->flops[i]<<"\n");
@@ -70,11 +71,11 @@
 	MARSHALLING_ENUM(ProfilerEnum);
 	pointer = &this->time[0];
-	MARSHALLING_DYNAMIC(pointer,IssmPDouble,MAXIMUMSIZE);
+	MARSHALLING_DYNAMIC(pointer,IssmPDouble,MAXPROFSIZE);
 	pointer = &this->flops[0];
-	MARSHALLING_DYNAMIC(pointer,IssmPDouble,MAXIMUMSIZE);
+	MARSHALLING_DYNAMIC(pointer,IssmPDouble,MAXPROFSIZE);
 	pointer = &this->memory[0];
-	MARSHALLING_DYNAMIC(pointer,IssmPDouble,MAXIMUMSIZE);
+	MARSHALLING_DYNAMIC(pointer,IssmPDouble,MAXPROFSIZE);
 	bpointer = &this->running[0];
-	MARSHALLING_DYNAMIC(bpointer,bool,MAXIMUMSIZE);
+	MARSHALLING_DYNAMIC(bpointer,bool,MAXPROFSIZE);
 
 } /*}}}*/
@@ -88,5 +89,5 @@
 	/*Get tag*/
 	_assert_(tag>=0); 
-	_assert_(tag<MAXIMUMSIZE); 
+	_assert_(tag<MAXPROFSIZE); 
 	if(this->running[tag]) _error_("Tag "<<tag<<" has not been stopped");
 
@@ -97,5 +98,5 @@
 	/*Get tag*/
 	_assert_(tag>=0); 
-	_assert_(tag<MAXIMUMSIZE); 
+	_assert_(tag<MAXPROFSIZE); 
 	if(this->running[tag]) _error_("Tag "<<tag<<" has not been stopped");
 
@@ -130,5 +131,5 @@
 	/*Get initial flops*/
 	_assert_(tag>=0); 
-	_assert_(tag<MAXIMUMSIZE); 
+	_assert_(tag<MAXPROFSIZE); 
 	if(this->running[tag]) _error_("Tag "<<tag<<" has not been stopped");
 
@@ -140,5 +141,5 @@
 	/*Check tag*/
 	_assert_(tag>=0); 
-	_assert_(tag<MAXIMUMSIZE); 
+	_assert_(tag<MAXPROFSIZE); 
 	if(this->running[tag]) _error_("Tag "<<tag<<" is already running");
 
@@ -167,5 +168,5 @@
 	/*Plug into this->time: */
 	_assert_(tag>=0); 
-	_assert_(tag<MAXIMUMSIZE); 
+	_assert_(tag<MAXPROFSIZE); 
 	this->time_start[tag]   = t;
 	this->flops_start[tag]  = f;
@@ -174,4 +175,5 @@
 	/*turn on running*/
 	this->running[tag] = true;
+	this->used[tag]    = true;
 }/*}}}*/
 void  Profiler::Stop(int tag,bool dontmpisync){/*{{{*/
@@ -179,5 +181,5 @@
 	/*Check tag*/
 	_assert_(tag>=0); 
-	_assert_(tag<MAXIMUMSIZE); 
+	_assert_(tag<MAXPROFSIZE); 
 	if(!this->running[tag]) _error_("Tag "<<tag<<" is not running");
 
@@ -206,5 +208,5 @@
 	/*Plug into this->time: */
 	_assert_(tag>=0); 
-	_assert_(tag<MAXIMUMSIZE); 
+	_assert_(tag<MAXPROFSIZE); 
 	this->time[tag]   += t - this->time_start[tag];
 	this->flops[tag]  += f - this->flops_start[tag];
@@ -214,2 +216,9 @@
 	this->running[tag] = false;
 }/*}}}*/
+bool  Profiler::Used(int tag){/*{{{*/
+
+	/*Check tag*/
+	_assert_(tag>=0); 
+	_assert_(tag<MAXPROFSIZE); 
+	return this->used[tag];
+}/*}}}*/
Index: issm/trunk/src/c/classes/Profiler.h
===================================================================
--- issm/trunk/src/c/classes/Profiler.h	(revision 23389)
+++ issm/trunk/src/c/classes/Profiler.h	(revision 23394)
@@ -11,21 +11,33 @@
 
 /*Macros*/
-#define TOTAL 0      /*Profiling Total time */ 
-#define MPROCESSOR 1 /*Profiling Model processor*/ 
-#define CORE 2       /*Profiling solution */ 
-#define SOLVER 3     /*Profiling solution */ 
-#define ADCORE 4     /*Profiling AD */ 
-#define MAXIMUMSIZE 5
+#define TOTAL              0 /*Profiling Total time */
+#define MPROCESSOR         1 /*Profiling Model processor*/
+#define CORE               2 /*Profiling solution */
+#define SOLVER             3 /*Profiling solution */
+#define ADCORE             4 /*Profiling AD */
+#define THERMALCORE			5 /*Profiling THERMAL */
+#define HYDROLOGYCORE		6 /*Profiling HYDROLOGY */
+#define STRESSBALANCECORE	7 /*Profiling STRESSBALANCE */
+#define DAMAGECORE			8 /*Profiling DAMAGE */
+#define MOVINGFRONTCORE		9 /*Profiling MOVINGFRONT */
+#define MASSTRANSPORTCORE	10 /*Profiling MASSTRANSPORT */
+#define SMBCORE				11 /*Profiling SMB */
+#define GROUNDINGLINECORE	12 /*Profiling GROUDINGLINE MIGRATION */
+#define GIACORE				13 /*Profiling GIA */
+#define ESACORE				14 /*Profiling ESA */
+#define SLRCORE				15 /*Profiling SLR */
+#define MAXPROFSIZE			16 /*Used to initialize static arrays*/
 
 class Profiler: public Object{
 
 	public: 
-		IssmPDouble flops[MAXIMUMSIZE];
-		IssmPDouble flops_start[MAXIMUMSIZE];
-		IssmPDouble memory[MAXIMUMSIZE];
-		IssmPDouble memory_start[MAXIMUMSIZE];
-		IssmPDouble time[MAXIMUMSIZE];
-		IssmPDouble time_start[MAXIMUMSIZE];
-		bool        running[MAXIMUMSIZE];
+		IssmPDouble flops[MAXPROFSIZE];
+		IssmPDouble flops_start[MAXPROFSIZE];
+		IssmPDouble memory[MAXPROFSIZE];
+		IssmPDouble memory_start[MAXPROFSIZE];
+		IssmPDouble time[MAXPROFSIZE];
+		IssmPDouble time_start[MAXPROFSIZE];
+		bool        running[MAXPROFSIZE];
+		bool        used[MAXPROFSIZE];
 
 		/*Profiler constructors, destructors */
@@ -48,6 +60,7 @@
 		int          TotalTimeModSec(int tag);
 		IssmPDouble  Memory(int tag);
-		void         Start(int tagenum,bool dontmpisync=false);
-		void         Stop(int tagenum,bool dontmpisync=false);
+		void         Start(int tagenum,bool dontmpisync=true); /*Do not call MPI barrier by default to save some ms*/
+		void         Stop(int tagenum, bool dontmpisync=true); /*Do not call MPI barrier by default to save some ms*/
+		bool         Used(int tagenum);
 };
 
Index: issm/trunk/src/c/cores/ad_core.cpp
===================================================================
--- issm/trunk/src/c/cores/ad_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/ad_core.cpp	(revision 23394)
@@ -19,4 +19,7 @@
 /*}}}*/
 
+#ifdef _HAVE_CODIPACK_
+CoDi_global codi_global = {};
+#endif
 void ad_core(FemModel* femmodel){
 
@@ -41,5 +44,5 @@
 	if(isautodiff && !iscontrol){
 
-		#ifdef _HAVE_ADOLC_
+		#if defined(_HAVE_ADOLC_)
 			if(VerboseAutodiff())_printf0_("   start ad core\n");
 
@@ -318,4 +321,65 @@
 			xDelete(axp); 
 			xDelete(driver);
+
+			#elif defined(_HAVE_CODIPACK_)
+			if(VerboseAutodiff())_printf0_("   start CoDiPack ad core\n");
+
+			/*First, stop tracing: */
+			auto& tape_codi = IssmDouble::getGlobalTape();
+			tape_codi.setPassive();
+
+			if(VerboseAutodiff()){ /*{{{*/
+				if(my_rank == 0) {
+					// FIXME codi "just because" for now
+					tape_codi.printStatistics(std::cout);
+					codi_global.print(std::cout);
+				}
+			}
+
+			/*retrieve parameters: */
+			femmodel->parameters->FindParam(&num_dependents,AutodiffNumDependentsEnum);
+			femmodel->parameters->FindParam(&num_independents,AutodiffNumIndependentsEnum);
+
+			/*if no dependents, no point in running a driver: */
+			if(!(num_dependents*num_independents)) return;
+
+			/*Branch according to AD driver: */
+			femmodel->parameters->FindParam(&driver,AutodiffDriverEnum);
+			if(VerboseAutodiff())_printf0_("   driver: " << driver << "\n");
+
+			if (strcmp(driver,"fos_reverse")==0) { /*{{{*/
+				if(VerboseAutodiff())_printf0_("   CoDiPack fos_reverse\n");
+				int     aDepIndex=0;
+				double *weightVectorTimesJac=NULL;
+
+				/*retrieve direction index: */
+				femmodel->parameters->FindParam(&aDepIndex,AutodiffFosReverseIndexEnum);
+				if (my_rank==0) {
+					if (aDepIndex<0 || aDepIndex>=num_dependents
+							|| codi_global.output_indices.size() <= aDepIndex){
+						_error_("index value for AutodiffFosReverseIndexEnum should be in [0,num_dependents-1]");
+					}
+					tape_codi.setGradient(codi_global.output_indices[aDepIndex], 1.0);
+				}
+
+				tape_codi.evaluate();
+
+				weightVectorTimesJac=xNew<double>(num_independents);
+				/*call driver: */
+				auto in_size = codi_global.input_indices.size();
+				for(size_t i = 0; i < in_size; ++i) {
+					weightVectorTimesJac[i] = tape_codi.getGradient(codi_global.input_indices[i]);
+				}
+
+				/*add to results*/
+				femmodel->results->AddObject(new GenericExternalResult<IssmPDouble*>(femmodel->results->Size()+1,AutodiffJacobianEnum,weightVectorTimesJac,num_independents,1,0,0.0));
+
+				/*free resources :*/
+				xDelete(weightVectorTimesJac);
+			} /*}}}*/
+			else _error_("driver: " << driver << " not yet supported!");
+
+			if(VerboseAutodiff())_printf0_("   end CoDiPack ad core\n");
+			xDelete(driver);
 		#else
 			_error_("Should not be requesting AD drivers when an AD library is not available!");
Index: issm/trunk/src/c/cores/adgradient_core.cpp
===================================================================
--- issm/trunk/src/c/cores/adgradient_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/adgradient_core.cpp	(revision 23394)
@@ -48,5 +48,5 @@
 	if(isautodiff){
 
-		#ifdef _HAVE_ADOLC_
+		#if defined(_HAVE_ADOLC_)
 			if(VerboseAutodiff())_printf0_("   start ad core\n"); 
 
@@ -182,4 +182,7 @@
 			xDelete(totalgradient);
 			xDelete(axp); /*}}}*/
+
+		#elif defined(_HAVE_CODIPACK_)
+			fprintf(stderr, "*** Codipack adgradient_core()\n");
 		#else
 			_error_("Should not be requesting AD drivers when an AD library is not available!");
Index: issm/trunk/src/c/cores/adjointstressbalance_core.cpp
===================================================================
--- issm/trunk/src/c/cores/adjointstressbalance_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/adjointstressbalance_core.cpp	(revision 23394)
@@ -31,7 +31,18 @@
 	if(VerboseSolution()) _printf0_("   computing velocities\n");
 	femmodel->SetCurrentConfiguration(StressbalanceAnalysisEnum);
+	
+	bool is_schur_cg_solver = false;
+	#ifdef _HAVE_PETSC_
+	int solver_type;
+	PetscOptionsDetermineSolverType(&solver_type);
+
+	if(solver_type==FSSolverEnum) is_schur_cg_solver = true;
+	#endif
+
 	if(isFS){
 		if (fe_FS==LATaylorHoodEnum || fe_FS==LACrouzeixRaviartEnum)
 		 solutionsequence_la(femmodel);
+		else if(is_schur_cg_solver)
+		 solutionsequence_schurcg(femmodel);
 		else
 		 solutionsequence_nonlinear(femmodel,conserve_loads); 
Index: issm/trunk/src/c/cores/balancethickness_core.cpp
===================================================================
--- issm/trunk/src/c/cores/balancethickness_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/balancethickness_core.cpp	(revision 23394)
@@ -21,5 +21,5 @@
 	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
 
-	if(VerboseSolution()) _printf0_("call computational core:\n");
+	if(VerboseSolution()) _printf0_("   call computational core:\n");
 	solutionsequence_linear(femmodel);
 
Index: issm/trunk/src/c/cores/balancevelocity_core.cpp
===================================================================
--- issm/trunk/src/c/cores/balancevelocity_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/balancevelocity_core.cpp	(revision 23394)
@@ -27,5 +27,5 @@
 	solutionsequence_linear(femmodel);
 
-	if(VerboseSolution()) _printf0_("call computational core:\n");
+	if(VerboseSolution()) _printf0_("   call computational core:\n");
 	femmodel->SetCurrentConfiguration(BalancevelocityAnalysisEnum);
 	solutionsequence_linear(femmodel);
Index: issm/trunk/src/c/cores/control_core.cpp
===================================================================
--- issm/trunk/src/c/cores/control_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/control_core.cpp	(revision 23394)
@@ -81,6 +81,6 @@
 	IssmDouble  *XL = NULL;
 	IssmDouble  *XU = NULL;
-	GetVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
-	GetVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
+	GetVectorFromControlInputsx(&XL,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
+	GetVectorFromControlInputsx(&XU,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
 	for(long i=0;i<nsize;i++){
 		if(X0[i]>XU[i]) X0[i]=XU[i];
@@ -97,5 +97,5 @@
 		femmodel->OutputControlsx(&femmodel->results);
 
-		#ifdef _HAVE_ADOLC_
+		#ifdef _HAVE_AD_
 		IssmPDouble* J_passive=xNew<IssmPDouble>(nsteps);
 		for(int i=0;i<nsteps;i++) J_passive[i]=reCast<IssmPDouble>(J[i]);
@@ -134,6 +134,6 @@
 	IssmDouble  *XL = NULL;
 	IssmDouble  *XU = NULL;
-	GetVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
-	GetVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
+	GetVectorFromControlInputsx(&XL,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
+	GetVectorFromControlInputsx(&XU,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
 	for(long i=0;i<nsize;i++){
 		if(X[i]>XU[i]) X[i]=XU[i];
@@ -143,5 +143,6 @@
 	/*Update control input*/
 	SetControlInputsFromVectorx(femmodel,X);
-
+	
+	
 	/*solve forward: */
 	switch(solution_type){
@@ -150,8 +151,21 @@
 			stressbalance_core(femmodel);	//We need a 3D velocity!! (vz is required for the next thermal run)
 			break;
-		case StressbalanceSolutionEnum:
+		case StressbalanceSolutionEnum:{
 			femmodel->SetCurrentConfiguration(StressbalanceAnalysisEnum);
-			solutionsequence_nonlinear(femmodel,conserve_loads); 
-			break;
+			
+			bool is_schur_cg_solver = false;
+			#ifdef _HAVE_PETSC_
+			int solver_type;
+			PetscOptionsDetermineSolverType(&solver_type);
+			if(solver_type==FSSolverEnum) is_schur_cg_solver = true;
+			#endif
+			
+			if(is_schur_cg_solver){
+			 solutionsequence_schurcg(femmodel);
+			}else{
+			 solutionsequence_nonlinear(femmodel,conserve_loads); 
+			}
+			}
+			 break;
 		case BalancethicknessSolutionEnum:
 			femmodel->SetCurrentConfiguration(BalancethicknessAnalysisEnum);
@@ -211,6 +225,6 @@
 	IssmDouble  *XL = NULL;
 	IssmDouble  *XU = NULL;
-	GetVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
-	GetVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
+	GetVectorFromControlInputsx(&XL,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
+	GetVectorFromControlInputsx(&XU,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
 	for(long i=0;i<nsize;i++){
 		if(X[i]>XU[i]) X[i]=XU[i];
Index: issm/trunk/src/c/cores/controlad_core.cpp
===================================================================
--- issm/trunk/src/c/cores/controlad_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/controlad_core.cpp	(revision 23394)
@@ -11,4 +11,5 @@
 #include "../solutionsequences/solutionsequences.h"
 
+/*This file is probably never used!*/
 #if defined (_HAVE_M1QN3_)  & defined (_HAVE_ADOLC_)
 /*m1qn3 prototypes {{{*/
Index: issm/trunk/src/c/cores/controladm1qn3_core.cpp
===================================================================
--- issm/trunk/src/c/cores/controladm1qn3_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/controladm1qn3_core.cpp	(revision 23394)
@@ -11,6 +11,11 @@
 #include "../solutionsequences/solutionsequences.h"
 
-#if defined (_HAVE_M1QN3_) && defined(_HAVE_ADOLC_)
-/*m1qn3 prototypes*/
+#ifdef _HAVE_CODIPACK_
+extern CoDi_global codi_global;
+#include <sstream> // for output of the CoDiPack tape
+#endif
+
+#if defined (_HAVE_M1QN3_) && defined(_HAVE_AD_)
+/*m1qn3 prototypes {{{*/
 extern "C" void *ctonbe_; // DIS mode : Conversion
 extern "C" void *ctcabe_; // DIS mode : Conversion
@@ -31,8 +36,10 @@
 	int*         i;
 } m1qn3_struct;
+/*}}}*/
 
 /*m1qm3 functions*/
 void simul_starttrace(FemModel* femmodel){/*{{{*/
 
+	#if defined(_HAVE_ADOLC_)
 	/*Retrive ADOLC parameters*/
 	IssmDouble gcTriggerRatio;
@@ -57,114 +64,48 @@
 	int my_rank=IssmComm::GetRank();
 	trace_on(my_rank,keepTaylors,reCast<size_t>(obufsize),reCast<size_t>(lbufsize),reCast<size_t>(cbufsize),reCast<size_t>(tbufsize),skipFileDeletion);
+
+	#elif defined(_HAVE_CODIPACK_)
+
+		//fprintf(stderr, "*** Codipack IoModel::StartTrace\n");
+		/*
+		 * FIXME codi
+		 * - ADOL-C variant uses fine grained tracing with various arguments
+		 * - ADOL-C variant sets a garbage collection parameter for its tape
+		 * -> These parameters are not read for the CoDiPack ISSM version!
+		 */
+		auto& tape_codi = IssmDouble::getGlobalTape();
+		tape_codi.setActive();
+		#if _AD_TAPE_ALLOC_
+		//alloc_profiler.Tag(StartInit, true);
+		IssmDouble x_t(1.0), y_t(1.0);
+		tape_codi.registerInput(y_t);
+		int codi_allocn = 0;
+		femmodel->parameters->FindParam(&codi_allocn,AutodiffTapeAllocEnum);
+		for(int i = 0;i < codi_allocn;++i) {
+			x_t = y_t * y_t;
+		}
+		/*
+		std::stringstream out_s;
+		IssmDouble::getGlobalTape().printStatistics(out_s);
+		_printf0_("StartTrace::Tape Statistics	   : TapeAlloc count=[" << codi_allocn << "]\n" << out_s.str());
+		*/
+		tape_codi.reset();
+		//alloc_profiler.Tag(FinishInit, true);
+		#else
+		tape_codi.reset();
+		#endif
+
+	#else
+	_error_("not implemented");
+	#endif
 }/*}}}*/
-void simul_ad(long* indic,long* n,double* X,double* pf,double* G,long izs[1],float rzs[1],void* dzs){/*{{{*/
-
-	/*Get rank*/
-	int my_rank=IssmComm::GetRank();
-
-	/*Recover Arguments*/
-	m1qn3_struct *input_struct = (m1qn3_struct*)dzs;
-
-	FemModel* femmodel = input_struct->femmodel;
-	int num_responses,num_controls,numberofvertices,solution_type;
-	femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
-	int* N = NULL;
-	int N_add = 0;
-	int* control_enum = NULL;
-
-	if (solution_type == TransientSolutionEnum){
-		femmodel = input_struct->femmodel->copy();
-	}
-
-	IssmPDouble*  Jlist        = input_struct->Jlist;
-	int           JlistM       = input_struct->M;
-	int           JlistN       = input_struct->N;
-	int*          Jlisti       = input_struct->i;
-	int           intn         = (int)*n;
-
-	/*Recover some parameters*/
-	IssmDouble* scaling_factors = NULL;
-	femmodel->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
-	femmodel->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
-	femmodel->parameters->FindParam(&scaling_factors,NULL,InversionControlScalingFactorsEnum);
-	femmodel->parameters->FindParam(&N,NULL,ControlInputSizeNEnum);
-	femmodel->parameters->FindParam(&control_enum,NULL,InversionControlParametersEnum);
-	numberofvertices=femmodel->vertices->NumberOfVertices();
-
-	/*Constrain input vector and update controls*/
-	double  *XL = NULL;
-	double  *XU = NULL;
-	GetPassiveVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
-	GetPassiveVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
-
-	N_add = 0;
-	for (int c=0;c<num_controls;c++){
-		for(int i=0;i<numberofvertices*N[c];i++){
-			int index = N_add*numberofvertices+i;
-			X[index] = X[index]*reCast<double>(scaling_factors[c]);
-			if(X[index]>XU[index]) X[index]=XU[index];
-			if(X[index]<XL[index]) X[index]=XL[index];
-		}
-		N_add+=N[c];
-	}
-
-	/*Start Tracing*/
-	simul_starttrace(femmodel);
-	/*Set X as our new control input and as INDEPENDENT*/
-#ifdef _HAVE_AD_
-	IssmDouble* aX=xNew<IssmDouble>(intn,"t");
-#else
-	IssmDouble* aX=xNew<IssmDouble>(intn);
-#endif
-	if(my_rank==0){
-		for(int i=0;i<intn;i++){
-			aX[i]<<=X[i];
-		}
-	}
-
-	ISSM_MPI_Bcast(aX,intn,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
-	SetControlInputsFromVectorx(femmodel,aX);
-	xDelete<IssmDouble>(aX);
-
-	/*Compute solution (forward)*/
-	void (*solutioncore)(FemModel*)=NULL;
-	CorePointerFromSolutionEnum(&solutioncore,femmodel->parameters,solution_type);
-	solutioncore(femmodel);
-
-	/*Reset the time to zero for next optimization*/
-	if(solution_type==TransientSolutionEnum){
-		IssmDouble restart_time;
-		femmodel->parameters->FindParam(&restart_time,TimesteppingStartTimeEnum);
-		femmodel->parameters->SetParam(restart_time,TimeEnum);
-
-	}
-
-	/*Get Dependents*/
-	IssmDouble  output_value;
-	int         num_dependents;
-	IssmPDouble *dependents;
-	DataSet*    dependent_objects=NULL;
-	IssmDouble	J=0.;
-	femmodel->parameters->FindParam(&num_dependents,AutodiffNumDependentsEnum);
-	femmodel->parameters->FindParam(&dependent_objects,AutodiffDependentObjectsEnum);
-
-	/*Go through our dependent variables, and compute the response:*/
-	dependents=xNew<IssmPDouble>(num_dependents);
-	for(int i=0;i<dependent_objects->Size();i++){
-		DependentObject* dep=(DependentObject*)dependent_objects->GetObjectByOffset(i);
-		if(solution_type==TransientSolutionEnum) output_value = dep->GetValue();
-		if(solution_type!=TransientSolutionEnum) dep->Responsex(&output_value,femmodel);
-		if (my_rank==0) {
-			output_value>>=dependents[i];
-			J+=output_value;
-		}
-	}
-
-	/*Turning off trace tape*/
+void simul_stoptrace(){/*{{{*/
+
+	#if defined(_HAVE_ADOLC_)
 	trace_off();
-time_t now = time(NULL);
-if(my_rank==0) _printf_("\nTIME: "<<now<<"\n");
-	/*Print tape statistics so that user can kill this run if something is off already:*/
 	if(VerboseAutodiff()){ /*{{{*/
+
+		#ifdef _HAVE_ADOLC_
+		int my_rank=IssmComm::GetRank();
 		size_t  tape_stats[15];
 		tapestats(my_rank,tape_stats); //reading of tape statistics
@@ -207,19 +148,171 @@
 		}
 		delete [] sstats;
+		#endif
+
+		#ifdef _HAVE_CODIPACK_
+		#ifdef _AD_TAPE_ALLOC_
+		//_printf_("Allocation time  P(" << my_rank << "): " << alloc_profiler.DeltaTime(StartInit, FinishInit) << "\n");
+		#endif
+		std::stringstream out_s;
+		IssmDouble::getGlobalTape().printStatistics(out_s);
+		_printf0_("CoDiPack Profiling::Tape Statistics :\n" << out_s.str());
+		#endif
 	} /*}}}*/
 
-	/*diverse: */
-	int  dummy;
-	int  num_independents=0;
+	#elif defined(_HAVE_CODIPACK_)
+	auto& tape_codi = IssmDouble::getGlobalTape();
+	tape_codi.setPassive();
+	if(VerboseAutodiff()){
+		int my_rank=IssmComm::GetRank();
+		if(my_rank == 0) {
+			// FIXME codi "just because" for now
+			tape_codi.printStatistics(std::cout);
+			codi_global.print(std::cout);
+		}
+	}
+	#else
+	_error_("not implemented");
+	#endif
+}/*}}}*/
+void simul_ad(long* indic,long* n,double* X,double* pf,double* G,long izs[1],float rzs[1],void* dzs){/*{{{*/
+
+	/*Get rank*/
+	int my_rank=IssmComm::GetRank();
+
+	/*Recover Arguments*/
+	m1qn3_struct *input_struct = (m1qn3_struct*)dzs;
+
+	FemModel* femmodel = input_struct->femmodel;
+	int num_responses,num_controls,solution_type;
+	femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
+
+	/*In transient, we need to make sure we do not modify femmodel at each iteration, make a copy*/
+	if(solution_type == TransientSolutionEnum) femmodel = input_struct->femmodel->copy();
+
+	IssmPDouble*  Jlist        = input_struct->Jlist;
+	int           JlistM       = input_struct->M;
+	int           JlistN       = input_struct->N;
+	int*          Jlisti       = input_struct->i;
+	int           intn         = (int)*n;
+
+	/*Recover some parameters*/
+	IssmDouble *scaling_factors = NULL;
+	int        *N               = NULL;
+	int        *control_enum    = NULL;
+	femmodel->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
+	femmodel->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
+	femmodel->parameters->FindParam(&scaling_factors,NULL,InversionControlScalingFactorsEnum);
+	femmodel->parameters->FindParam(&N,NULL,ControlInputSizeNEnum);
+	femmodel->parameters->FindParam(&control_enum,NULL,InversionControlParametersEnum);
+	int numberofvertices=femmodel->vertices->NumberOfVertices();
+
+	/*Constrain input vector and update controls*/
+	double  *XL = NULL;
+	double  *XU = NULL;
+	GetPassiveVectorFromControlInputsx(&XL,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
+	GetPassiveVectorFromControlInputsx(&XU,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
+
+	int N_add = 0;
+	for (int c=0;c<num_controls;c++){
+		for(int i=0;i<numberofvertices*N[c];i++){
+			int index = N_add*numberofvertices+i;
+			X[index] = X[index]*reCast<double>(scaling_factors[c]);
+			if(X[index]>XU[index]) X[index]=XU[index];
+			if(X[index]<XL[index]) X[index]=XL[index];
+		}
+		N_add+=N[c];
+	}
+
+	/*Start Tracing*/
+	simul_starttrace(femmodel);
+	/*Set X as our new control input and as INDEPENDENT*/
+#ifdef _HAVE_AD_
+	IssmDouble* aX=xNew<IssmDouble>(intn,"t");
+#else
+	IssmDouble* aX=xNew<IssmDouble>(intn);
+#endif
+
+	#if defined(_HAVE_ADOLC_)
+	if(my_rank==0){
+		for(int i=0;i<intn;i++){
+			aX[i]<<=X[i];
+		}
+	}
+	#elif defined(_HAVE_CODIPACK_)
+	auto& tape_codi = IssmDouble::getGlobalTape();
+	codi_global.input_indices.clear();
+	if(my_rank==0){
+		for (int i=0;i<intn;i++) {
+			aX[i]=X[i];
+			tape_codi.registerInput(aX[i]);
+			codi_global.input_indices.push_back(aX[i].getGradientData());
+		}
+	}
+	#else
+	_error_("not suppoted");
+	#endif
+
+	ISSM_MPI_Bcast(aX,intn,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
+	SetControlInputsFromVectorx(femmodel,aX);
+	xDelete<IssmDouble>(aX);
+
+	/*Compute solution (forward)*/
+	void (*solutioncore)(FemModel*)=NULL;
+	CorePointerFromSolutionEnum(&solutioncore,femmodel->parameters,solution_type);
+	solutioncore(femmodel);
+
+	/*Reset the time to zero for next optimization*/
+	if(solution_type==TransientSolutionEnum){
+		IssmDouble restart_time;
+		femmodel->parameters->FindParam(&restart_time,TimesteppingStartTimeEnum);
+		femmodel->parameters->SetParam(restart_time,TimeEnum);
+
+	}
+
+	/*Get Dependents*/
+	IssmDouble  output_value;
+	int         num_dependents;
+	IssmPDouble *dependents;
+	DataSet*    dependent_objects=NULL;
+	IssmDouble	J=0.;
+	femmodel->parameters->FindParam(&num_dependents,AutodiffNumDependentsEnum);
+	femmodel->parameters->FindParam(&dependent_objects,AutodiffDependentObjectsEnum);
+
+	/*Go through our dependent variables, and compute the response:*/
+	dependents=xNew<IssmPDouble>(num_dependents);
+	#if defined(_HAVE_CODIPACK_)
+	codi_global.output_indices.clear();
+	#endif
+	for(int i=0;i<dependent_objects->Size();i++){
+		DependentObject* dep=(DependentObject*)dependent_objects->GetObjectByOffset(i);
+		if(solution_type==TransientSolutionEnum) output_value = dep->GetValue();
+		if(solution_type!=TransientSolutionEnum) dep->Responsex(&output_value,femmodel);
+		if(my_rank==0) {
+
+			#if defined(_HAVE_CODIPACK_)
+			tape_codi.registerOutput(output_value);
+			dependents[i] = output_value.getValue();
+			codi_global.output_indices.push_back(output_value.getGradientData());
+
+			#elif defined(_HAVE_ADOLC_)
+			output_value>>=dependents[i];
+
+			#else
+			_error_("not suppoted");
+			#endif
+			J+=output_value;
+		}
+	}
+
+	/*Turning off trace tape*/
+	simul_stoptrace();
+	//time_t now = time(NULL);
+	//if(my_rank==0) _printf_("\nTIME: "<<now<<"\n");
 
 	/*intermediary: */
+	int          num_independents=intn;
 	IssmPDouble *aWeightVector=NULL;
 	IssmPDouble *weightVectorTimesJac=NULL;
-
-	/*output: */
-	IssmPDouble *totalgradient=NULL;
-
-	/*retrieve parameters: */
-	num_independents = intn;
+	IssmPDouble *totalgradient=xNewZeroInit<IssmPDouble>(num_independents);
 
 	/*if no dependents, no point in running a driver: */
@@ -229,4 +322,7 @@
 	int num_dependents_old   = num_dependents;
 	int num_independents_old = num_independents;
+
+	#if defined(_HAVE_ADOLC_)
+	/*Get gradient for ADOLC {{{*/
 	if(my_rank!=0){
 		num_dependents   = 0;
@@ -243,6 +339,4 @@
 	/* Ok, now we are going to call the fos_reverse in a loop on the index, from 0 to num_dependents, so
 	 * as to generate num_dependents gradients: */
-	totalgradient=xNewZeroInit<IssmPDouble>(num_independents_old);
-
 	for(int aDepIndex=0;aDepIndex<num_dependents_old;aDepIndex++){
 
@@ -277,4 +371,41 @@
 		xDelete(aWeightVector);
 	}
+	/*}}}*/
+	#elif defined(_HAVE_CODIPACK_)
+	/*Get gradient for CoDiPack{{{*/
+	if(VerboseAutodiff())_printf0_("   CoDiPack fos_reverse\n");
+
+	/* call the fos_reverse in a loop on the index, from 0 to num_dependents, so
+	 * as to generate num_dependents gradients: */
+	for(int aDepIndex=0;aDepIndex<num_dependents_old;aDepIndex++){
+
+		/*initialize direction index in the weights vector: */
+		aWeightVector=xNewZeroInit<IssmPDouble>(num_dependents);
+		if(my_rank==0){
+			if(aDepIndex<0 || aDepIndex>=num_dependents || codi_global.output_indices.size() <= aDepIndex){
+				_error_("index value for AutodiffFosReverseIndexEnum should be in [0,num_dependents-1]");
+			}
+			tape_codi.setGradient(codi_global.output_indices[aDepIndex],1.0);
+		}
+		tape_codi.evaluate();
+
+		/*Get gradient for this dependent */
+		weightVectorTimesJac=xNew<IssmPDouble>(num_independents);
+		auto in_size = codi_global.input_indices.size();
+		for(size_t i = 0; i < in_size; ++i) {
+			_assert_(i<num_independents);
+			weightVectorTimesJac[i] = tape_codi.getGradient(codi_global.input_indices[i]);
+		}
+		if(my_rank==0) for(int i=0;i<num_independents;i++) {
+			totalgradient[i]+=weightVectorTimesJac[i];
+		}
+		/*free resources :*/
+		xDelete(weightVectorTimesJac);
+		xDelete(aWeightVector);
+	}
+	/*}}}*/
+	#else
+	_error_("not suppoted");
+	#endif
 
 	/*Broadcast gradient to other ranks*/
@@ -293,10 +424,4 @@
 	Jlist[(*Jlisti)*JlistN+num_responses] = reCast<IssmPDouble>(J);
 
-/*
-	IssmDouble* test = xNew<IssmDouble>(intn);
-	femmodel->parameters->FindParam(&test,NULL,InversionXBestEnum);
-	for(int i=0;i<10;i++)_printf_("X "<<test[i]<<"\n");
-	xDelete<IssmDouble>(intn);
-*/
 	if(*indic==0){
 		/*dry run, no gradient required*/
@@ -341,4 +466,6 @@
 	xDelete<double>(XU);
 	xDelete<double>(XL);
+	xDelete<int>(control_enum);
+	xDelete<int>(N);
 	xDelete<IssmDouble>(scaling_factors);
 	xDelete<IssmPDouble>(totalgradient);
@@ -394,10 +521,5 @@
 
 	/*Get initial guess*/
-	Vector<double> *Xpetsc = NULL;
-
-	GetPassiveVectorFromControlInputsx(&Xpetsc,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"value");
-	X = Xpetsc->ToMPISerial();
-	Xpetsc->GetSize(&intn);
-	delete Xpetsc;
+	GetPassiveVectorFromControlInputsx(&X,&intn,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"value");
 	//_assert_(intn==numberofvertices*num_controls);
 
@@ -458,6 +580,6 @@
 	double  *XL = NULL;
 	double  *XU = NULL;
-	GetPassiveVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
-	GetPassiveVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
+	GetPassiveVectorFromControlInputsx(&XL,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
+	GetPassiveVectorFromControlInputsx(&XU,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
 
 	N_add = 0;
@@ -479,5 +601,5 @@
 		aX[i] = reCast<IssmDouble>(X[i]); 
 		aG[i] = reCast<IssmDouble>(G[i]);
-		}
+	}
 
 	ControlInputSetGradientx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,aG);
@@ -538,4 +660,4 @@
 
 #else
-void controladm1qn3_core(FemModel* femmodel){_error_("M1QN3 or ADOLC not installed");}
+void controladm1qn3_core(FemModel* femmodel){_error_("M1QN3 or ADOLC/CoDiPack not installed");}
 #endif //_HAVE_M1QN3_
Index: issm/trunk/src/c/cores/controlm1qn3_core.cpp
===================================================================
--- issm/trunk/src/c/cores/controlm1qn3_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/controlm1qn3_core.cpp	(revision 23394)
@@ -11,6 +11,6 @@
 #include "../solutionsequences/solutionsequences.h"
 
-#if defined (_HAVE_M1QN3_) && !defined(_HAVE_ADOLC_)
-/*m1qn3 prototypes*/
+#if defined (_HAVE_M1QN3_)
+/*m1qn3 prototypes {{{*/
 extern "C" void *ctonbe_; // DIS mode : Conversion
 extern "C" void *ctcabe_; // DIS mode : Conversion
@@ -28,21 +28,22 @@
 /*Use struct to provide arguments*/
 typedef struct{
-	FemModel  * femmodel;
-	IssmDouble* Jlist;
+	FemModel   * femmodel;
+	IssmPDouble* Jlist;
 	int         M;
 	int         N;
 	int*        i;
 } m1qn3_struct;
-
-void controlm1qn3_core(FemModel* femmodel){
+/*}}}*/
+
+void controlm1qn3_core(FemModel* femmodel){/*{{{*/
 
 	/*Intermediaries*/
-	long         omode;
-	double       f,dxmin,gttol; 
-	int          maxsteps,maxiter;
-	int          intn,numberofvertices,num_controls,num_cost_functions,solution_type;
-	IssmDouble  *scaling_factors = NULL;
-	IssmDouble  *X  = NULL;
-	IssmDouble  *G  = NULL;
+	long    omode;
+	double  f,dxmin,gttol; 
+	int     maxsteps,maxiter;
+	int     intn,numberofvertices,num_controls,num_cost_functions,solution_type;
+	double *scaling_factors = NULL;
+	double *X  = NULL;
+	double *G  = NULL;
 
 	/*Recover some parameters*/
@@ -52,7 +53,7 @@
 	femmodel->parameters->FindParam(&maxsteps,InversionMaxstepsEnum);
 	femmodel->parameters->FindParam(&maxiter,InversionMaxiterEnum);
-	femmodel->parameters->FindParam(&dxmin,InversionDxminEnum);
-	femmodel->parameters->FindParam(&gttol,InversionGttolEnum);
-	femmodel->parameters->FindParam(&scaling_factors,NULL,InversionControlScalingFactorsEnum);
+	femmodel->parameters->FindParamAndMakePassive(&dxmin,InversionDxminEnum);
+	femmodel->parameters->FindParamAndMakePassive(&gttol,InversionGttolEnum);
+	femmodel->parameters->FindParamAndMakePassive(&scaling_factors,NULL,InversionControlScalingFactorsEnum);
 	femmodel->parameters->SetParam(false,SaveResultsEnum);
 	numberofvertices=femmodel->vertices->NumberOfVertices();
@@ -77,9 +78,5 @@
 
 	/*Get initial guess*/
-	Vector<IssmDouble> *Xpetsc = NULL;
-	GetVectorFromControlInputsx(&Xpetsc,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"value");
-	X = Xpetsc->ToMPISerial();
-	Xpetsc->GetSize(&intn);
-	delete Xpetsc;
+	GetPassiveVectorFromControlInputsx(&X,&intn,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"value");
 	_assert_(intn==numberofvertices*num_controls);
 
@@ -111,5 +108,5 @@
 	mystruct.M        = maxiter;
 	mystruct.N        = num_cost_functions+1;
-	mystruct.Jlist    = xNewZeroInit<IssmDouble>(mystruct.M*mystruct.N);
+	mystruct.Jlist    = xNewZeroInit<IssmPDouble>(mystruct.M*mystruct.N);
 	mystruct.i        = xNewZeroInit<int>(1);
 
@@ -127,4 +124,5 @@
 				&reverse,&indic,izs,rzs,(void*)&mystruct);
 
+	/*Print exit flag*/
 	switch(int(omode)){
 		case 0:  _printf0_("   Stop requested (indic = 0)\n"); break;
@@ -140,8 +138,8 @@
 
 	/*Constrain solution vector*/
-	IssmDouble  *XL = NULL;
-	IssmDouble  *XU = NULL;
-	GetVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
-	GetVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
+	double  *XL = NULL;
+	double  *XU = NULL;
+	GetPassiveVectorFromControlInputsx(&XL,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
+	GetPassiveVectorFromControlInputsx(&XU,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
 	for(int c=0;c<num_controls;c++){
 		for(int i=0;i<numberofvertices;i++){
@@ -152,6 +150,22 @@
 		}
 	}
+
+	/*Set X as our new control (need to recast)*/
+	#ifdef _HAVE_AD_
+	IssmDouble* aX=xNew<IssmDouble>(intn);
+	IssmDouble* aG=xNew<IssmDouble>(intn);
+	for(int i=0;i<intn;i++) {
+		aX[i] = reCast<IssmDouble>(X[i]); 
+		aG[i] = reCast<IssmDouble>(G[i]);
+	}
+	ControlInputSetGradientx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,aG);
+	SetControlInputsFromVectorx(femmodel,aX);
+	xDelete(aX);
+	xDelete(aG);
+	#else
 	SetControlInputsFromVectorx(femmodel,X);
 	ControlInputSetGradientx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,G);
+	#endif
+
 	femmodel->OutputControlsx(&femmodel->results);
 	femmodel->results->AddObject(new GenericExternalResult<double*>(femmodel->results->Size()+1,JEnum,mystruct.Jlist,(*mystruct.i),mystruct.N,0,0));
@@ -173,13 +187,11 @@
 	xDelete<double>(mystruct.Jlist);
 	xDelete<int>(mystruct.i);
-}
-
-/*Cost function definition*/
-void simul(long* indic,long* n,double* X,double* pf,double* G,long izs[1],float rzs[1],void* dzs){
+}/*}}}*/
+void simul(long* indic,long* n,double* X,double* pf,double* G,long izs[1],float rzs[1],void* dzs){/*{{{*/
 
 	/*Recover Arguments*/
 	m1qn3_struct *input_struct = (m1qn3_struct*)dzs;
 	FemModel     *femmodel     = input_struct->femmodel;
-	IssmDouble   *Jlist        = input_struct->Jlist;
+	IssmPDouble  *Jlist        = input_struct->Jlist;
 	int           JlistM       = input_struct->M;
 	int           JlistN       = input_struct->N;
@@ -188,16 +200,16 @@
 	/*Recover some parameters*/
 	int num_responses,num_controls,numberofvertices,solution_type;
-	IssmDouble* scaling_factors = NULL;
+	double* scaling_factors = NULL;
 	femmodel->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
 	femmodel->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
-	femmodel->parameters->FindParam(&scaling_factors,NULL,InversionControlScalingFactorsEnum);
+	femmodel->parameters->FindParamAndMakePassive(&scaling_factors,NULL,InversionControlScalingFactorsEnum);
 	femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
 	numberofvertices=femmodel->vertices->NumberOfVertices();
 
 	/*Constrain input vector and update controls*/
-	IssmDouble  *XL = NULL;
-	IssmDouble  *XU = NULL;
-	GetVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
-	GetVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
+	double *XL = NULL;
+	double *XU = NULL;
+	GetPassiveVectorFromControlInputsx(&XL,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
+	GetPassiveVectorFromControlInputsx(&XU,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
 	for(int c=0;c<num_controls;c++){
 		for(int i=0;i<numberofvertices;i++){
@@ -208,5 +220,12 @@
 		}
 	}
+	#ifdef _HAVE_AD_
+	IssmDouble* aX=xNew<IssmDouble>(*n);
+	for(int i=0;i<*n;i++) aX[i] = reCast<IssmDouble>(X[i]); 
+	SetControlInputsFromVectorx(femmodel,aX);
+	xDelete(aX);
+	#else
 	SetControlInputsFromVectorx(femmodel,X);
+	#endif
 
 	/*Compute solution and adjoint*/
@@ -222,9 +241,11 @@
 	/*Compute objective function*/
 	IssmDouble* Jtemp = NULL;
-	femmodel->CostFunctionx(pf,&Jtemp,NULL);
+	IssmDouble  J;
+	femmodel->CostFunctionx(&J,&Jtemp,NULL);
+	*pf = reCast<double>(J);
 	_printf0_("f(x) = "<<setw(12)<<setprecision(7)<<*pf<<"  |  ");
 
 	/*Record cost function values and delete Jtemp*/
-	for(int i=0;i<num_responses;i++) Jlist[(*Jlisti)*JlistN+i] = Jtemp[i];
+	for(int i=0;i<num_responses;i++) Jlist[(*Jlisti)*JlistN+i] = reCast<double>(Jtemp[i]);
 	Jlist[(*Jlisti)*JlistN+num_responses] = *pf;
 	xDelete<IssmDouble>(Jtemp);
@@ -239,6 +260,6 @@
 
 		*Jlisti = (*Jlisti) +1;
-		xDelete<IssmDouble>(XU);
-		xDelete<IssmDouble>(XL);
+		xDelete<double>(XU);
+		xDelete<double>(XL);
 		return;
 	}
@@ -251,5 +272,5 @@
 	IssmDouble* G2 = NULL;
 	Gradjx(&G2,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
-	for(long i=0;i<*n;i++) G[i] = -G2[i];
+	for(long i=0;i<*n;i++) G[i] = -reCast<double>(G2[i]);
 	xDelete<IssmDouble>(G2);
 
@@ -275,12 +296,10 @@
 	/*Clean-up and return*/
 	*Jlisti = (*Jlisti) +1;
-	xDelete<IssmDouble>(XU);
-	xDelete<IssmDouble>(XL);
-	xDelete<IssmDouble>(scaling_factors);
-}
+	xDelete<double>(XU);
+	xDelete<double>(XL);
+	xDelete<double>(scaling_factors);
+}/*}}}*/
 
 #else
-void controlm1qn3_core(FemModel* femmodel){
-	_error_("M1QN3 not installed");
-}
+void controlm1qn3_core(FemModel* femmodel){_error_("M1QN3 not installed");}
 #endif //_HAVE_M1QN3_
Index: issm/trunk/src/c/cores/controlvalidation_core.cpp
===================================================================
--- issm/trunk/src/c/cores/controlvalidation_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/controlvalidation_core.cpp	(revision 23394)
@@ -9,19 +9,157 @@
 #include "../modules/modules.h"
 
+#ifdef _HAVE_CODIPACK_
+extern CoDi_global codi_global;
+#include <sstream> // for output of the CoDiPack tape
+#endif
+
+#ifdef _HAVE_AD_
+void simul_starttrace2(FemModel* femmodel){/*{{{*/
+
+	#if defined(_HAVE_ADOLC_)
+	/*Retrive ADOLC parameters*/
+	IssmDouble gcTriggerRatio;
+	IssmDouble gcTriggerMaxSize;
+	IssmDouble obufsize;
+	IssmDouble lbufsize;
+	IssmDouble cbufsize;
+	IssmDouble tbufsize;
+	femmodel->parameters->FindParam(&gcTriggerRatio,AutodiffGcTriggerRatioEnum);
+	femmodel->parameters->FindParam(&gcTriggerMaxSize,AutodiffGcTriggerMaxSizeEnum);
+	femmodel->parameters->FindParam(&obufsize,AutodiffObufsizeEnum);
+	femmodel->parameters->FindParam(&lbufsize,AutodiffLbufsizeEnum);
+	femmodel->parameters->FindParam(&cbufsize,AutodiffCbufsizeEnum);
+	femmodel->parameters->FindParam(&tbufsize,AutodiffTbufsizeEnum);
+
+	/*Set garbage collection parameters: */
+	setStoreManagerControl(reCast<IssmPDouble>(gcTriggerRatio),reCast<size_t>(gcTriggerMaxSize));
+
+	/*Start trace: */
+	int skipFileDeletion=1;
+	int keepTaylors=1;
+	int my_rank=IssmComm::GetRank();
+	trace_on(my_rank,keepTaylors,reCast<size_t>(obufsize),reCast<size_t>(lbufsize),reCast<size_t>(cbufsize),reCast<size_t>(tbufsize),skipFileDeletion);
+
+	#elif defined(_HAVE_CODIPACK_)
+
+		//fprintf(stderr, "*** Codipack IoModel::StartTrace\n");
+		/*
+		 * FIXME codi
+		 * - ADOL-C variant uses fine grained tracing with various arguments
+		 * - ADOL-C variant sets a garbage collection parameter for its tape
+		 * -> These parameters are not read for the CoDiPack ISSM version!
+		 */
+		auto& tape_codi = IssmDouble::getGlobalTape();
+		tape_codi.setActive();
+		#if _AD_TAPE_ALLOC_
+		//alloc_profiler.Tag(StartInit, true);
+		IssmDouble x_t(1.0), y_t(1.0);
+		tape_codi.registerInput(y_t);
+		int codi_allocn = 0;
+		femmodel->parameters->FindParam(&codi_allocn,AutodiffTapeAllocEnum);
+		for(int i = 0;i < codi_allocn;++i) {
+			x_t = y_t * y_t;
+		}
+		/*
+		std::stringstream out_s;
+		IssmDouble::getGlobalTape().printStatistics(out_s);
+		_printf0_("StartTrace::Tape Statistics	   : TapeAlloc count=[" << codi_allocn << "]\n" << out_s.str());
+		*/
+		tape_codi.reset();
+		//alloc_profiler.Tag(FinishInit, true);
+		#else
+		tape_codi.reset();
+		#endif
+
+	#else
+	_error_("not implemented");
+	#endif
+}/*}}}*/
+void simul_stoptrace2(){/*{{{*/
+
+	#if defined(_HAVE_ADOLC_)
+	trace_off();
+	if(VerboseAutodiff()){ /*{{{*/
+
+		#ifdef _HAVE_ADOLC_
+		int my_rank=IssmComm::GetRank();
+		size_t  tape_stats[15];
+		tapestats(my_rank,tape_stats); //reading of tape statistics
+		int commSize=IssmComm::GetSize();
+		int *sstats=new int[7];
+		sstats[0]=tape_stats[NUM_OPERATIONS];
+		sstats[1]=tape_stats[OP_FILE_ACCESS];
+		sstats[2]=tape_stats[NUM_LOCATIONS];
+		sstats[3]=tape_stats[LOC_FILE_ACCESS];
+		sstats[4]=tape_stats[NUM_VALUES];
+		sstats[5]=tape_stats[VAL_FILE_ACCESS];
+		sstats[6]=tape_stats[TAY_STACK_SIZE];
+		int *rstats=NULL;
+		if (my_rank==0) rstats=new int[commSize*7];
+		ISSM_MPI_Gather(sstats,7,ISSM_MPI_INT,rstats,7,ISSM_MPI_INT,0,IssmComm::GetComm());
+		if (my_rank==0) {
+			int offset=50;
+			int rOffset=(commSize/10)+1;
+			_printf_("   ADOLC statistics: \n");
+			_printf_("     "<<setw(offset)<<left<<"#independents: " <<setw(12)<<right<<tape_stats[NUM_INDEPENDENTS] << "\n");
+			_printf_("     "<<setw(offset)<<left<<"#dependents: " <<setw(12)<<right<<tape_stats[NUM_DEPENDENTS] << "\n");
+			_printf_("     "<<setw(offset)<<left<<"max #live active variables: " <<setw(12)<<right<<tape_stats[NUM_MAX_LIVES] << "\n");
+			_printf_("     operations: entry size "<< sizeof(unsigned char) << " Bytes \n");
+			_printf_("     "<<setw(offset)<<left<<"  #entries in buffer (AutodiffObufsizeEnum) " <<setw(12)<<right<<tape_stats[OP_BUFFER_SIZE] << "\n");
+			for (int r=0;r<commSize;++r)
+			 _printf_("       ["<<setw(rOffset)<<right<<r<<"]"<<setw(offset-rOffset-4)<<left<<" #entries total" <<setw(12)<<right<<rstats[r*7+0] << (rstats[r*7+1]?" ->file":"") << "\n");
+			_printf_("     locations: entry size " << sizeof(locint) << " Bytes\n");
+			_printf_("     "<<setw(offset)<<left<<"  #entries in buffer (AutodiffLbufsizeEnum) " <<setw(12)<<right<<tape_stats[LOC_BUFFER_SIZE] << "\n");
+			for (int r=0;r<commSize;++r)
+			 _printf_("       ["<<setw(rOffset)<<right<<r<<"]"<<setw(offset-rOffset-4)<<left<<" #entries total" <<setw(12)<<right<<rstats[r*7+2] << (rstats[r*7+3]?" ->file":"") << "\n");
+			_printf_("     constant values: entry size " << sizeof(double) << " Bytes\n");
+			_printf_("     "<<setw(offset)<<left<<"  #entries in buffer (AutodiffCbufsizeEnum) " <<setw(12)<<right<<tape_stats[VAL_BUFFER_SIZE] << "\n");
+			for (int r=0;r<commSize;++r)
+			 _printf_("       ["<<setw(rOffset)<<right<<r<<"]"<<setw(offset-rOffset-4)<<left<<" #entries total" <<setw(12)<<right<<rstats[r*7+4] << (rstats[r*7+5]?" ->file":"") << "\n");
+			_printf_("     Taylor stack: entry size " << sizeof(revreal) << " Bytes\n");
+			_printf_("     "<<setw(offset)<<left<<"  #entries in buffer (AutodiffTbufsizeEnum) " <<setw(12)<<right<<tape_stats[TAY_BUFFER_SIZE] << "\n");
+			for (int r=0;r<commSize;++r)
+			 _printf_("       ["<<setw(rOffset)<<right<<r<<"]"<<setw(offset-rOffset-4)<<left<<" #entries total" <<setw(12)<<right<<rstats[r*7+6] << (rstats[r*7+6]>tape_stats[TAY_BUFFER_SIZE]?" ->file":"") << "\n");
+			delete []rstats;
+		}
+		delete [] sstats;
+		#endif
+
+		#ifdef _HAVE_CODIPACK_
+		#ifdef _AD_TAPE_ALLOC_
+		//_printf_("Allocation time  P(" << my_rank << "): " << alloc_profiler.DeltaTime(StartInit, FinishInit) << "\n");
+		#endif
+		std::stringstream out_s;
+		IssmDouble::getGlobalTape().printStatistics(out_s);
+		_printf0_("CoDiPack Profiling::Tape Statistics :\n" << out_s.str());
+		#endif
+	} /*}}}*/
+
+	#elif defined(_HAVE_CODIPACK_)
+	auto& tape_codi = IssmDouble::getGlobalTape();
+	tape_codi.setPassive();
+	if(VerboseAutodiff()){
+		int my_rank=IssmComm::GetRank();
+		if(my_rank == 0) {
+			// FIXME codi "just because" for now
+			tape_codi.printStatistics(std::cout);
+			codi_global.print(std::cout);
+		}
+	}
+	#else
+	_error_("not implemented");
+	#endif
+}/*}}}*/
+#endif
+
 void controlvalidation_core(FemModel* femmodel){
 
 	int         solution_type,n;
 	int         num_responses;
-	IssmDouble  j0,j,yts;
+	IssmDouble  j0,j;
 	IssmDouble  Ialpha,exponent,alpha;
 	IssmDouble* scaling_factors = NULL;
 	IssmDouble* jlist = NULL;
-	IssmDouble *G = NULL;
-	IssmDouble *X = NULL;
-	IssmDouble *X0= NULL;
-
-	/*Solution and Adjoint core pointer*/
-	void (*solutioncore)(FemModel*) = NULL;
-	void (*adjointcore)(FemModel*)  = NULL;
+	int my_rank=IssmComm::GetRank();
 
 	/*Recover parameters used throughout the solution*/
@@ -29,19 +167,92 @@
 	femmodel->parameters->SetParam(false,SaveResultsEnum);
 	femmodel->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
-	femmodel->parameters->FindParam(&yts,ConstantsYtsEnum);
 	femmodel->parameters->FindParam(&scaling_factors,NULL,InversionControlScalingFactorsEnum);
 
 	/*Get initial guess*/
-	Vector<IssmDouble> *Xpetsc = NULL;
-	GetVectorFromControlInputsx(&Xpetsc,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"value");
-	Xpetsc->GetSize(&n);
-	X0 = Xpetsc->ToMPISerial();
-	delete Xpetsc;
-
-	/*Allocate current vector*/
-	X = xNew<IssmDouble>(n);
+	IssmPDouble* X0 = NULL;
+	GetPassiveVectorFromControlInputsx(&X0,&n,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"value");
+
+	/*Allocate vectors*/
+	IssmDouble*  X = xNew<IssmDouble>(n);
+	IssmPDouble* G = xNew<IssmPDouble>(n);
 
 	/*out of solution_type, figure out solution core and adjoint function pointer*/
+	void (*solutioncore)(FemModel*)=NULL;
 	CorePointerFromSolutionEnum(&solutioncore,femmodel->parameters,solution_type);
+
+	#if defined(_HAVE_ADOLC_)
+	/*{{{*/
+	IssmDouble* aX=xNew<IssmDouble>(n);
+	if(my_rank==0){
+		for(int i=0;i<n;i++){
+			aX[i]<<=X0[i];
+		}
+	}
+	_error_("not implemented yet...");
+	/*}}}*/
+	#elif defined(_HAVE_CODIPACK_)
+	simul_starttrace2(femmodel);
+	IssmDouble* aX=xNew<IssmDouble>(n);
+	auto& tape_codi = IssmDouble::getGlobalTape();
+	codi_global.input_indices.clear();
+	if(my_rank==0){
+		for (int i=0;i<n;i++) {
+			aX[i]=X0[i];
+			tape_codi.registerInput(aX[i]);
+			codi_global.input_indices.push_back(aX[i].getGradientData());
+		}
+	}
+	SetControlInputsFromVectorx(femmodel,aX);
+	xDelete(aX);
+
+	if(VerboseControl()) _printf0_("   Compute Initial cost function\n");
+	solutioncore(femmodel);
+
+	/*Get Dependents*/
+	IssmDouble  output_value;
+	int         num_dependents;
+	IssmPDouble *dependents;
+	DataSet*    dependent_objects=NULL;
+	IssmDouble	J=0.;
+	femmodel->parameters->FindParam(&num_dependents,AutodiffNumDependentsEnum);
+	femmodel->parameters->FindParam(&dependent_objects,AutodiffDependentObjectsEnum);
+
+	/*Go through our dependent variables, and compute the response:*/
+	dependents=xNew<IssmPDouble>(num_dependents);
+	codi_global.output_indices.clear();
+	for(int i=0;i<dependent_objects->Size();i++){
+		DependentObject* dep=(DependentObject*)dependent_objects->GetObjectByOffset(i);
+		if(solution_type==TransientSolutionEnum){
+			output_value = dep->GetValue();
+		}
+		else{
+			dep->Responsex(&output_value,femmodel);
+		}
+		_printf0_("=== output ="<<output_value<<" \n");
+		if(my_rank==0) {
+			tape_codi.registerOutput(output_value);
+			dependents[i] = output_value.getValue();
+			codi_global.output_indices.push_back(output_value.getGradientData());
+			J+=output_value;
+		}
+	}
+	j0 = J;
+	_printf0_("Initial cost function J(x) = "<<setw(12)<<setprecision(7)<<j0<<"\n");
+	_assert_(j0>0.); 
+	simul_stoptrace2();
+	/*initialize direction index in the weights vector: */
+	if(my_rank==0){
+		tape_codi.setGradient(codi_global.output_indices[0],1.0);
+	}
+	tape_codi.evaluate();
+
+	/*Get gradient for this dependent */
+	auto in_size = codi_global.input_indices.size();
+	for(size_t i = 0; i < in_size; ++i) {
+		G[i] = tape_codi.getGradient(codi_global.input_indices[i]);
+	}
+	#else
+	/*{{{*/
+	void (*adjointcore)(FemModel*)  = NULL;
 	AdjointCorePointerFromSolutionEnum(&adjointcore,solution_type);
 
@@ -59,4 +270,6 @@
 	Gradjx(&G,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
 	for(int i=0;i<n;i++) G[i] = -G[i];
+	/*}}}*/
+	#endif
 
 	/*Allocate output*/
@@ -76,9 +289,25 @@
 		SetControlInputsFromVectorx(femmodel,X);
 		solutioncore(femmodel);
+
+		#if defined(_HAVE_CODIPACK_)
+		j=0.;
+		for(int i=0;i<dependent_objects->Size();i++){
+			DependentObject* dep=(DependentObject*)dependent_objects->GetObjectByOffset(i);
+			if(solution_type==TransientSolutionEnum){
+				output_value = dep->GetValue();
+			}
+			else{
+				dep->Responsex(&output_value,femmodel);
+			}
+			j+=output_value;
+		}
+		#else
 		femmodel->CostFunctionx(&j,NULL,NULL);
+		#endif
 
 		IssmDouble Den = 0.;
 		for(int i=0;i<n;i++) Den += alpha* G[i] * scaling_factors[0];
 		Ialpha = fabs((j - j0)/Den - 1.);
+		_assert_(fabs(Den)>0.); 
 
 		_printf0_(" " << setw(11) << setprecision (5)<<alpha<<" " << setw(11) << setprecision (5)<<Ialpha<<"\n");
@@ -88,20 +317,24 @@
 
 	/*output*/
-	#ifdef _HAVE_ADOLC_
+	#ifdef _HAVE_AD_
 	IssmPDouble* J_passive=xNew<IssmPDouble>(2*num);
 	for(int i=0;i<2*num;i++) J_passive[i]=reCast<IssmPDouble>(output[i]);
 	femmodel->results->AddObject(new GenericExternalResult<IssmPDouble*>(femmodel->results->Size()+1,JEnum,J_passive,num,2,0,0));
 	xDelete<IssmPDouble>(J_passive);
+	IssmDouble* aG=xNew<IssmDouble>(n);
+	for(int i=0;i<n;i++) aG[i] = G[i];
+	ControlInputSetGradientx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,aG);
+	xDelete<IssmDouble>(aG);
 	#else
 	femmodel->results->AddObject(new GenericExternalResult<IssmPDouble*>(femmodel->results->Size()+1,JEnum,output,num,2,0,0));
+	ControlInputSetGradientx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,G);
 	#endif
-	ControlInputSetGradientx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,G);
 	femmodel->OutputControlsx(&femmodel->results);
 
 	/*Clean up and return*/
 	xDelete<IssmDouble>(output);
-	xDelete<IssmDouble>(G);
+	xDelete<IssmPDouble>(G);
 	xDelete<IssmDouble>(X);
-	xDelete<IssmDouble>(X0);
+	xDelete<double>(X0);
 	xDelete<IssmDouble>(scaling_factors);
 }
Index: issm/trunk/src/c/cores/damage_core.cpp
===================================================================
--- issm/trunk/src/c/cores/damage_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/damage_core.cpp	(revision 23394)
@@ -11,5 +11,8 @@
 
 void damage_core(FemModel* femmodel){
-
+	
+	/*Start profiler*/
+	femmodel->profiler->Start(DAMAGECORE);
+        
 	/*intermediary*/
 	bool   save_results;
@@ -48,3 +51,6 @@
 		xDelete<char*>(requested_outputs);
 	}
+	
+	/*End profiler*/
+	femmodel->profiler->Stop(DAMAGECORE);
 }
Index: issm/trunk/src/c/cores/esa_core.cpp
===================================================================
--- issm/trunk/src/c/cores/esa_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/esa_core.cpp	(revision 23394)
@@ -11,4 +11,7 @@
 
 void esa_core(FemModel* femmodel){ /*{{{*/
+
+	/*Start profiler*/
+	femmodel->profiler->Start(ESACORE);
 
 	Vector<IssmDouble> *U_radial  = NULL; 
@@ -112,4 +115,7 @@
 		if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);}
 	}
+	
+	/*End profiler*/
+	femmodel->profiler->Stop(ESACORE);
 
 } 
Index: issm/trunk/src/c/cores/gia_core.cpp
===================================================================
--- issm/trunk/src/c/cores/gia_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/gia_core.cpp	(revision 23394)
@@ -10,4 +10,7 @@
 #include "../solutionsequences/solutionsequences.h"
 void gia_core(FemModel* femmodel){
+
+	/*Start profiler*/
+	femmodel->profiler->Start(GIACORE);
 
 	Vector<IssmDouble> *wg    = NULL;
@@ -56,3 +59,6 @@
 	xDelete<IssmDouble>(x);
 	xDelete<IssmDouble>(y);
+	
+	/*End profiler*/
+	femmodel->profiler->Stop(GIACORE);
 }
Index: issm/trunk/src/c/cores/hydrology_core.cpp
===================================================================
--- issm/trunk/src/c/cores/hydrology_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/hydrology_core.cpp	(revision 23394)
@@ -11,4 +11,7 @@
 
 void hydrology_core(FemModel* femmodel){
+
+	/*Start profiler*/
+	femmodel->profiler->Start(HYDROLOGYCORE);
 
 	/*intermediary*/
@@ -47,5 +50,4 @@
 		/*intermediary: */
 		bool       isefficientlayer;
-		bool       isthermal;
 		int        step,hydroslices;
 		IssmDouble time,init_time,hydrotime,yts;
@@ -59,5 +61,4 @@
 		femmodel->parameters->FindParam(&yts,ConstantsYtsEnum);
 
-		femmodel->parameters->FindParam(&isthermal,TransientIsthermalEnum);
 		/*first we exclude frozen nodes of the solved nodes*/
 		femmodel->SetCurrentConfiguration(HydrologyDCInefficientAnalysisEnum);
@@ -150,3 +151,6 @@
 		xDelete<char*>(requested_outputs);
 	}
+
+	/*End profiler*/
+	femmodel->profiler->Stop(HYDROLOGYCORE);
 }
Index: issm/trunk/src/c/cores/masstransport_core.cpp
===================================================================
--- issm/trunk/src/c/cores/masstransport_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/masstransport_core.cpp	(revision 23394)
@@ -11,4 +11,7 @@
 
 void masstransport_core(FemModel* femmodel){
+
+	/*Start profiler*/
+	femmodel->profiler->Start(MASSTRANSPORTCORE);
 
 	/*parameters: */
@@ -81,3 +84,6 @@
 	/*Free ressources:*/
 	if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);}
+
+	/*profiler*/
+	femmodel->profiler->Stop(MASSTRANSPORTCORE);
 }
Index: issm/trunk/src/c/cores/movingfront_core.cpp
===================================================================
--- issm/trunk/src/c/cores/movingfront_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/movingfront_core.cpp	(revision 23394)
@@ -11,4 +11,7 @@
 
 void movingfront_core(FemModel* femmodel){
+	
+	/*Start profiler*/
+	femmodel->profiler->Start(MOVINGFRONTCORE);
 
 	/* intermediaries */
@@ -98,3 +101,6 @@
 		femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],1);
 	}
+	
+	/*End profiler*/
+	femmodel->profiler->Stop(MOVINGFRONTCORE);
 }
Index: issm/trunk/src/c/cores/sealevelrise_core.cpp
===================================================================
--- issm/trunk/src/c/cores/sealevelrise_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/sealevelrise_core.cpp	(revision 23394)
@@ -13,4 +13,7 @@
 void sealevelrise_core(FemModel* femmodel){ /*{{{*/
 
+	/*Start profiler*/
+	femmodel->profiler->Start(SLRCORE);
+
 	/*Parameters, variables:*/
 	bool save_results;
@@ -54,4 +57,7 @@
 	/*requested dependents: */
 	if(solution_type==SealevelriseSolutionEnum)femmodel->RequestedDependentsx();
+	
+	/*End profiler*/
+	femmodel->profiler->Stop(SLRCORE);
 }
 /*}}}*/
Index: issm/trunk/src/c/cores/smb_core.cpp
===================================================================
--- issm/trunk/src/c/cores/smb_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/smb_core.cpp	(revision 23394)
@@ -11,5 +11,8 @@
 
 void smb_core(FemModel* femmodel){
-
+	
+	/*Start profiler*/
+	femmodel->profiler->Start(SMBCORE);
+	
 	/*parameters: */
 	Analysis* analysis=NULL;
@@ -45,3 +48,6 @@
 	/*Free ressources:*/
 	if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);}
+
+	/*End profiler*/
+	femmodel->profiler->Stop(SMBCORE);
 }
Index: issm/trunk/src/c/cores/stressbalance_core.cpp
===================================================================
--- issm/trunk/src/c/cores/stressbalance_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/stressbalance_core.cpp	(revision 23394)
@@ -12,4 +12,7 @@
 
 void stressbalance_core(FemModel* femmodel){
+
+	/*Start profiler*/
+	femmodel->profiler->Start(STRESSBALANCECORE);
 
 	/*parameters: */
@@ -37,5 +40,4 @@
 
 	if(VerboseSolution()) _printf0_("   computing new velocity\n");
-
 	/*Compute slopes if necessary */
 	if(isSIA || (isFS && domaintype==Domain2DverticalEnum)) surfaceslope_core(femmodel);
@@ -73,4 +75,8 @@
 	/*Compute vertical velocities*/
 	if (domaintype==Domain3DEnum && (isSIA || isSSA || isL1L2 || isHO)){
+
+		/*We need basal melt rates for vertical velocity*/
+		bmb_core(femmodel);
+
 		analysis = new StressbalanceVerticalAnalysis();
 		analysis->Core(femmodel);
@@ -87,3 +93,6 @@
 	/*Free ressources:*/	
 	if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);}
+
+	/*End profiler*/
+	femmodel->profiler->Stop(STRESSBALANCECORE);
 }
Index: issm/trunk/src/c/cores/thermal_core.cpp
===================================================================
--- issm/trunk/src/c/cores/thermal_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/thermal_core.cpp	(revision 23394)
@@ -12,5 +12,8 @@
 
 void thermal_core(FemModel* femmodel){
-
+	
+	/*Start profiler*/
+        femmodel->profiler->Start(THERMALCORE);
+	
 	/*intermediary*/
 	bool   save_results,isenthalpy;
@@ -52,4 +55,6 @@
 	/*Free ressources:*/	
 	if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);}
-
+	
+	/*End profiler*/
+        femmodel->profiler->Stop(THERMALCORE);
 }
Index: issm/trunk/src/c/cores/transient_core.cpp
===================================================================
--- issm/trunk/src/c/cores/transient_core.cpp	(revision 23389)
+++ issm/trunk/src/c/cores/transient_core.cpp	(revision 23394)
@@ -70,5 +70,5 @@
 	if(numoutputs) femmodel->parameters->FindParam(&requested_outputs,&numoutputs,TransientRequestedOutputsEnum);
 
-	#if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_)
+	#if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
 	if(amr_frequency){
 		femmodel->parameters->FindParam(&amr_restart,AmrRestartEnum);
@@ -78,5 +78,5 @@
 
 	if(isoceancoupling){ /*{{{*/
-		#ifndef _HAVE_ADOLC_
+		#ifndef _HAVE_AD_
 		if(VerboseSolution()) _printf0_("   ocean coupling: initialization \n");
 		int my_rank;
@@ -180,5 +180,5 @@
 		for(int i=0;i<ngrids_ocean;i++) if(icemask_oceangrid[i]>0.) icebase_oceangrid[i]=+9999.;
 		xDelete<IssmDouble>(icemask_oceangrid);
-			
+
 		if(my_rank==0){
 			ISSM_MPI_Send(icebase_oceangrid,ngrids_ocean,ISSM_MPI_DOUBLE,0,10001008,tomitgcmcomm);
@@ -247,5 +247,5 @@
 		if(isoceancoupling){ /*{{{*/
 
-			#ifndef _HAVE_ADOLC_
+			#ifndef _HAVE_AD_
 			if(VerboseSolution()) _printf0_("   ocean coupling: exchanging information\n");
 			int my_rank;
@@ -371,10 +371,12 @@
 				femmodel->parameters->FindParam(&smb_model,SmbEnum);
 				if(isenthalpy){
-					if(smb_model==SMBpddEnum)     ResetBoundaryConditions(femmodel,EnthalpyAnalysisEnum);
-					if(smb_model==SMBd18opddEnum) ResetBoundaryConditions(femmodel,EnthalpyAnalysisEnum);
+					if(smb_model==SMBpddEnum)				ResetBoundaryConditions(femmodel,EnthalpyAnalysisEnum);
+					if(smb_model==SMBd18opddEnum)			ResetBoundaryConditions(femmodel,EnthalpyAnalysisEnum);
+					if(smb_model==SMBpddSicopolisEnum)	ResetBoundaryConditions(femmodel,EnthalpyAnalysisEnum);
 				}
 				else{
-					if(smb_model==SMBpddEnum)     ResetBoundaryConditions(femmodel,ThermalAnalysisEnum);
-					if(smb_model==SMBd18opddEnum) ResetBoundaryConditions(femmodel,ThermalAnalysisEnum);
+					if(smb_model==SMBpddEnum)				ResetBoundaryConditions(femmodel,ThermalAnalysisEnum);
+					if(smb_model==SMBd18opddEnum)			ResetBoundaryConditions(femmodel,ThermalAnalysisEnum);
+					if(smb_model==SMBpddSicopolisEnum)	ResetBoundaryConditions(femmodel,ThermalAnalysisEnum);
 				}
 			}
@@ -382,4 +384,7 @@
 		}
 
+		/*shifting smb position to have runoff value*/
+		if(issmb) smb_core(femmodel);
+
 		if(ishydrology) hydrology_core(femmodel);
 
@@ -391,6 +396,5 @@
 
 		/* from here on, prepare geometry for next time step*/
-
-		if(issmb) smb_core(femmodel);
+		//if(issmb) smb_core(femmodel);
 
 		if(ismasstransport){
@@ -401,4 +405,8 @@
 
 		if(isgroundingline){
+
+			/*Start profiler*/
+			femmodel->profiler->Start(GROUNDINGLINECORE);
+
 			if(VerboseSolution()) _printf0_("   computing new grounding line position\n");
 			GroundinglineMigrationx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
@@ -410,4 +418,7 @@
 			femmodel->parameters->SetParam(SurfaceEnum,InputToExtrudeEnum);
 			extrudefrombase_core(femmodel);
+
+			/*Stop profiler*/
+			femmodel->profiler->Stop(GROUNDINGLINECORE);
 
 			if(save_results){
@@ -453,5 +464,5 @@
 		if(amr_frequency){
 
-			#if !defined(_HAVE_ADOLC_)
+			#if !defined(_HAVE_AD_)
 			if(save_results) femmodel->WriteMeshInResults();
 			if(step%amr_frequency==0 && time<finaltime){
@@ -461,5 +472,5 @@
 
 			#else
-			_error_("AMR not suppored with ADOLC");
+			_error_("AMR not suppored with AD");
 			#endif
 		}
Index: issm/trunk/src/c/modules/CoordinateSystemTransformx/CoordinateSystemTransformx.cpp
===================================================================
--- issm/trunk/src/c/modules/CoordinateSystemTransformx/CoordinateSystemTransformx.cpp	(revision 23389)
+++ issm/trunk/src/c/modules/CoordinateSystemTransformx/CoordinateSystemTransformx.cpp	(revision 23394)
@@ -9,5 +9,5 @@
 #include <proj_api.h>
 
-void CoordinateSystemTransformx(IssmDouble** px_dest,IssmDouble** py_dest,IssmDouble* x_src,IssmDouble* y_src,int size,const char* str_src,const char* str_dst){
+void CoordinateSystemTransformx(double** px_dest,double** py_dest,double* x_src,double* y_src,int size,const char* str_src,const char* str_dst){
 
 #if !defined(_HAVE_PROJ4_)
@@ -17,6 +17,6 @@
 	/*Allocate output and initialize values as src*/
 	_assert_(size>0);
-	IssmDouble* x_dest = xNew<IssmDouble>(size);
-	IssmDouble* y_dest = xNew<IssmDouble>(size);
+	double* x_dest = xNew<double>(size);
+	double* y_dest = xNew<double>(size);
 	for(int i=0;i<size;i++){
 		x_dest[i] = x_src[i];
Index: issm/trunk/src/c/modules/CoordinateSystemTransformx/CoordinateSystemTransformx.h
===================================================================
--- issm/trunk/src/c/modules/CoordinateSystemTransformx/CoordinateSystemTransformx.h	(revision 23389)
+++ issm/trunk/src/c/modules/CoordinateSystemTransformx/CoordinateSystemTransformx.h	(revision 23394)
@@ -8,4 +8,4 @@
 
 /* local prototypes: */
-void CoordinateSystemTransformx(IssmDouble** px_dest,IssmDouble** py_dest,IssmDouble* x_src,IssmDouble* y_src,int size,const char* str_src,const char* str_dst);
+void CoordinateSystemTransformx(double** px_dest,double** py_dest,double* x_src,double* y_src,int size,const char* str_src,const char* str_dst);
 #endif  
Index: issm/trunk/src/c/modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.cpp
===================================================================
--- issm/trunk/src/c/modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.cpp	(revision 23389)
+++ issm/trunk/src/c/modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.cpp	(revision 23394)
@@ -78,5 +78,6 @@
 		IssmDouble val=sqrt(dmax_basin[i]/dist_max)*(maxbox-1);
 
-		#ifdef _HAVE_ADOLC_
+		#ifdef _HAVE_AD_
+		_error_("Check the implementation of floor below");
 		/*Do not use floor when AD is on*/
 		int k=0; while(k<val+.5){k++;}
Index: issm/trunk/src/c/modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.cpp
===================================================================
--- issm/trunk/src/c/modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.cpp	(revision 23389)
+++ issm/trunk/src/c/modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.cpp	(revision 23394)
@@ -78,49 +78,26 @@
 
 }/*}}}*/
-void GetVectorFromControlInputsx( IssmDouble** pvector, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters, const char* data){/*{{{*/
+void GetVectorFromControlInputsx( IssmDouble** pvector,int *pN, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters, const char* data){/*{{{*/
 
 	/*intermediary: */
+	int                 N;
 	Vector<IssmDouble>* vec_vector=NULL;
 
+	/*Get PETSc vector*/
 	GetVectorFromControlInputsx( &vec_vector, elements,nodes, vertices, loads, materials, parameters,data);
+
+	/*Serialize*/
+	vec_vector->GetSize(&N);
 	IssmDouble* vector=vec_vector->ToMPISerial();
-
-	/*Free ressources:*/
 	delete vec_vector;
 
 	/*Assign output pointers:*/
 	*pvector=vector;
+	if(pN) *pN=N;
 }/*}}}*/
 
 /*For autodiff, we sometimes need to cast our vectors to passive*/
-#ifdef _HAVE_ADOLC_
-void GetPassiveVectorFromControlInputsx(Vector<IssmPDouble>** pvector, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters,const char* data){/*{{{*/
-
-	/*Get active vector first*/
-	Vector<IssmDouble>*   activevector=NULL;
-	Vector<IssmPDouble>*  vector=NULL;
-	int                   size;
-
-	/*Retrieve some parameters*/
-	GetVectorFromControlInputsx(&activevector, elements,nodes, vertices, loads, materials, parameters,data);
-
-	/*Serialize vector*/
-	activevector->GetSize(&size);
-	IssmDouble* dactivevector=activevector->ToMPISerial();
-
-	/*Cast to passive*/
-	vector=new Vector<IssmPDouble>(size);
-	for(int i=0;i<size;i++){
-		vector->SetValue(i,reCast<IssmPDouble>(dactivevector[i]),INS_VAL);
-	}
-	vector->Assemble();
-
-	/*Assign output pointers:*/
-	delete activevector;
-	xDelete<IssmDouble>(dactivevector);
-	*pvector=vector;
-
-}/*}}}*/
-void GetPassiveVectorFromControlInputsx(IssmPDouble** pvector, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters, const char* data){/*{{{*/
+#ifdef _HAVE_AD_
+void GetPassiveVectorFromControlInputsx(IssmPDouble** pvector,int* pN, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters, const char* data){/*{{{*/
 
 	/*Get active vector first*/
@@ -144,15 +121,11 @@
 	xDelete<IssmDouble>(dactivevector);
 	*pvector=vector;
+	if(pN) *pN=size;
 
 }/*}}}*/
 #else
-void GetPassiveVectorFromControlInputsx(Vector<IssmPDouble>** pvector, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters,const char* data){/*{{{*/
+void GetPassiveVectorFromControlInputsx(IssmPDouble** pvector,int* pN, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters, const char* data){/*{{{*/
 
-	GetVectorFromControlInputsx(pvector, elements,nodes, vertices, loads, materials, parameters,data);
-
-}/*}}}*/
-void GetPassiveVectorFromControlInputsx(IssmPDouble** pvector, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters, const char* data){/*{{{*/
-
-	GetVectorFromControlInputsx(pvector, elements,nodes, vertices, loads, materials, parameters,data);
+	GetVectorFromControlInputsx(pvector,pN,elements,nodes, vertices, loads, materials, parameters,data);
 }/*}}}*/
 #endif
Index: issm/trunk/src/c/modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.h
===================================================================
--- issm/trunk/src/c/modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.h	(revision 23389)
+++ issm/trunk/src/c/modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.h	(revision 23394)
@@ -9,8 +9,7 @@
 /* local prototypes: */
 void	GetVectorFromControlInputsx( Vector<IssmDouble>** pvector, Elements* elements,Nodes* nodes, Vertices* vertices,Loads* loads, Materials* materials,  Parameters* parameters,const char* data="value");
-void	GetVectorFromControlInputsx( IssmDouble** pvector, Elements* elements,Nodes* nodes, Vertices* vertices,Loads* loads, Materials* materials,  Parameters* parameters,const char* data="value");
+void	GetVectorFromControlInputsx( IssmDouble** pvector,int* pN, Elements* elements,Nodes* nodes, Vertices* vertices,Loads* loads, Materials* materials,  Parameters* parameters,const char* data="value");
 
-void	GetPassiveVectorFromControlInputsx(Vector<double>** pvector, Elements* elements,Nodes* nodes, Vertices* vertices,Loads* loads, Materials* materials,  Parameters* parameters,const char* data="value");
-void	GetPassiveVectorFromControlInputsx(double** pvector, Elements* elements,Nodes* nodes, Vertices* vertices,Loads* loads, Materials* materials,  Parameters* parameters,const char* data="value");
+void	GetPassiveVectorFromControlInputsx(double** pvector,int* pN, Elements* elements,Nodes* nodes, Vertices* vertices,Loads* loads, Materials* materials,  Parameters* parameters,const char* data="value");
 
 #endif  /* _GETVECTORFROMCONTROLINPUTSXX_H */
Index: issm/trunk/src/c/modules/ModelProcessorx/Autodiff/CreateParametersAutodiff.cpp
===================================================================
--- issm/trunk/src/c/modules/ModelProcessorx/Autodiff/CreateParametersAutodiff.cpp	(revision 23389)
+++ issm/trunk/src/c/modules/ModelProcessorx/Autodiff/CreateParametersAutodiff.cpp	(revision 23394)
@@ -73,7 +73,36 @@
 		xDelete<char>(options);
 		/*}}}*/
+		#elif _HAVE_CODIPACK_
+		//fprintf(stderr, "*** Codipack CreateParametersAutodiff()\n");
+		/*initialize a placeholder to store solver pointers: {{{*/
+		/*Solver pointers depend on what type of solver we are implementing: */
+		options=OptionsFromAnalysis(&toolkit,parameters,DefaultAnalysisEnum);
+		ToolkitOptions::Init(toolkit,options);
+		xDelete<char>(toolkit);
+
+		switch(IssmSolverTypeFromToolkitOptions()){
+			case MumpsEnum:{
+				#ifndef _HAVE_MUMPS_
+				_error_("CoDiPack: requesting mumps solver without MUMPS being compiled in!");
+				#endif
+				break;
+				}
+			case GslEnum: {
+				#ifndef _HAVE_GSL_
+				_error_("CoDiPack: requesting GSL solver without GSL being compiled in!");
+				#endif
+				break;
+				}
+			default:
+							_error_("solver type not supported yet!");
+		}
+		/*Free ressources: */
+		xDelete<char>(options);
+		#endif
+		#if defined(_HAVE_AD_) 
 
 	if(isautodiff){
-		/*Copy some parameters from IoModel to parameters dataset: {{{*/
+		#if defined(_HAVE_ADOLC_)
+		/*Copy some parameters from IoModel to parameters dataset*/
 		parameters->AddObject(iomodel->CopyConstantObject("md.autodiff.obufsize",AutodiffObufsizeEnum));
 		parameters->AddObject(iomodel->CopyConstantObject("md.autodiff.cbufsize",AutodiffCbufsizeEnum));
@@ -82,5 +111,12 @@
 		parameters->AddObject(iomodel->CopyConstantObject("md.autodiff.gcTriggerRatio",AutodiffGcTriggerRatioEnum));
 		parameters->AddObject(iomodel->CopyConstantObject("md.autodiff.gcTriggerMaxSize",AutodiffGcTriggerMaxSizeEnum));
-		/*}}}*/
+
+		#elif defined(_HAVE_CODIPACK_)
+		parameters->AddObject(iomodel->CopyConstantObject("md.autodiff.tapeAlloc",AutodiffTapeAllocEnum));
+
+		#else
+		_error_("not supported yet");
+		#endif
+
 		/*retrieve driver: {{{*/
 		iomodel->FindConstant(&autodiff_driver,"md.autodiff.driver");
@@ -88,4 +124,8 @@
 
 		if(strcmp(autodiff_driver,"fos_forward")==0){
+#if _HAVE_CODIPACK_
+			// FIXME codi support Foward Mode (scalar)
+			_error_("Foward Mode (scalar) not supported yet!");
+#endif
 			parameters->AddObject(iomodel->CopyConstantObject("md.autodiff.fos_forward_index",AutodiffFosForwardIndexEnum));
 		}
@@ -94,4 +134,8 @@
 		}
 		else if(strcmp(autodiff_driver,"fov_forward")==0){
+#if _HAVE_CODIPACK_
+			// FIXME codi support Foward Mode (vector)
+			_error_("Foward Mode (vector) not supported yet!");
+#endif
 			/*Retrieve list of indices: */
 			iomodel->FetchData(&indices,&num_indices,&dummy,"md.autodiff.fov_forward_indices");
Index: issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp
===================================================================
--- issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp	(revision 23389)
+++ issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp	(revision 23394)
@@ -9,5 +9,4 @@
 #include "../ModelProcessorx.h"
 
-#if !defined(_HAVE_ADOLC_)
 void	UpdateElementsAndMaterialsControl(Elements* elements,Parameters* parameters,Materials* materials, IoModel* iomodel){
 	/*Intermediary*/
@@ -20,4 +19,12 @@
 	char     **controls         = NULL;
 	char     **cost_functions   = NULL;
+
+	/*Fetch parameters: */
+	bool isautodiff;
+	iomodel->FindConstant(&isautodiff,"md.autodiff.isautodiff");
+	if(isautodiff){
+		UpdateElementsAndMaterialsControlAD(elements,parameters,materials,iomodel);
+		return;
+	}
 
 	/*Fetch parameters: */
@@ -126,7 +133,7 @@
 	xDelete<char*>(controls);
 }
-#else 
-void UpdateElementsAndMaterialsControl(Elements* elements,Parameters* parameters,Materials* materials, IoModel* iomodel){
-
+void UpdateElementsAndMaterialsControlAD(Elements* elements,Parameters* parameters,Materials* materials, IoModel* iomodel){
+
+	#if defined(_HAVE_AD_)
 	/*Intermediaries*/
 	int				num_independent_objects,M,N,M_par,N_par;
@@ -222,7 +229,10 @@
 	xDelete<IssmDouble>(independents_fullmax);
 	xDelete<int>(start_point);
+	xDelete<int>(control_sizes);
 	/*Step2: create cost functions (dependents)*/
 
 	return;
+#else 
+	_error_("AD not compiled");
+#endif
 }
-#endif
Index: issm/trunk/src/c/modules/ModelProcessorx/CreateNodes.cpp
===================================================================
--- issm/trunk/src/c/modules/ModelProcessorx/CreateNodes.cpp	(revision 23389)
+++ issm/trunk/src/c/modules/ModelProcessorx/CreateNodes.cpp	(revision 23394)
@@ -32,5 +32,5 @@
 				for(j=0;j<3;j++){
 					if(my_nodes[3*i+j]){ 
-						nodes->AddObject(new Node(id0+3*i+j+1,id0+3*i+j,lid++,iomodel->elements[+3*i+j]-1,iomodel,analysis,approximation));
+						nodes->AddObject(new Node(id0+3*i+j+1,id0+3*i+j,lid++,iomodel->elements[3*i+j]-1,iomodel,analysis,approximation));
 
 					}
Index: issm/trunk/src/c/modules/ModelProcessorx/CreateParameters.cpp
===================================================================
--- issm/trunk/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 23389)
+++ issm/trunk/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 23394)
@@ -374,5 +374,5 @@
 	ParseToolkitsOptionsx(parameters,toolkitsoptionsfid);
 
-	#ifdef _HAVE_ADOLC_
+	#ifdef _HAVE_AD_
 	if(VerboseMProcessor()) _printf0_("   starting autodiff parameters \n");
 	CreateParametersAutodiff(parameters,iomodel);
Index: issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.h
===================================================================
--- issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.h	(revision 23389)
+++ issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.h	(revision 23394)
@@ -19,4 +19,5 @@
 void CreateOutputDefinitions(Elements* elements, Parameters* parameters,IoModel* iomodel);
 void UpdateElementsAndMaterialsControl(Elements* elements,Parameters* parameters,Materials* materials, IoModel* iomodel);
+void UpdateElementsAndMaterialsControlAD(Elements* elements,Parameters* parameters,Materials* materials, IoModel* iomodel);
 void UpdateElementsAndMaterialsDakota(Elements* elements,Materials* materials, IoModel* iomodel);
 void UpdateElementsTransient(Elements* elements,Parameters* parameters,IoModel* iomodel,int analysis_type);
Index: issm/trunk/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp
===================================================================
--- issm/trunk/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp	(revision 23389)
+++ issm/trunk/src/c/modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp	(revision 23394)
@@ -33,4 +33,6 @@
 
 		xDelete<int>(control_type);
+		xDelete<int>(M);
+		xDelete<int>(N);
 	}
 	else{
Index: issm/trunk/src/c/modules/SurfaceMassBalancex/Gembx.cpp
===================================================================
--- issm/trunk/src/c/modules/SurfaceMassBalancex/Gembx.cpp	(revision 23389)
+++ issm/trunk/src/c/modules/SurfaceMassBalancex/Gembx.cpp	(revision 23394)
@@ -62,5 +62,5 @@
 	//into specified top structure depth (zTop). Also make sure top grid cell
 	//structure length (dzTop) is greater than 5 cm
-	#ifndef _HAVE_ADOLC_  //avoid the round operation check!
+	#ifndef _HAVE_AD_  //avoid the round operation check!
 	if (dgpTop != round(dgpTop)){ 
 		_error_("top grid cell structure length does not go evenly into specified top structure depth, adjust dzTop or zTop");
@@ -425,9 +425,9 @@
 			// spectral range:
 			// 0.3 - 0.8um
-			IssmDouble a0 = fmin(0.98, 1 - 1.58 *pow(gsz,0.5));
+			IssmDouble a0 = min(0.98, 1 - 1.58 *pow(gsz,0.5));
 			// 0.8 - 1.5um
-			IssmDouble a1 = fmax(0, 0.95 - 15.4 *pow(gsz,0.5));
+			IssmDouble a1 = max(0., 0.95 - 15.4 *pow(gsz,0.5));
 			// 1.5 - 2.8um
-			IssmDouble a2 = fmax(0.127, 0.88 + 346.3*gsz - 32.31*pow(gsz,0.5));
+			IssmDouble a2 = max(0.127, 0.88 + 346.3*gsz - 32.31*pow(gsz,0.5));
 
 			// broadband surface albedo
@@ -667,5 +667,5 @@
 	// NS: 2.16.18 divided dt by scaling factor, default set to 1/11 for stability
 	dt=1e12; 
-	for(int i=0;i<m;i++)dt = fmin(dt,CI * pow(dz[i],2) * d[i]  / (3 * K[i]) * thermo_scaling);
+	for(int i=0;i<m;i++)dt = min(dt,CI * pow(dz[i],2) * d[i]  / (3 * K[i]) * thermo_scaling);
 
 	// smallest possible even integer of 60 min where diffusion number > 1/2
@@ -752,5 +752,5 @@
 		// less when Ts is taken as the mean of the x top grid cells.
 		Ts = (T[0] + T[1])/2.0;
-		Ts = fmin(CtoK,Ts);    // don't allow Ts to exceed 273.15 K (0 degC)
+		Ts = min(CtoK,Ts);    // don't allow Ts to exceed 273.15 K (0 degC)
 
 		//TURBULENT HEAT FLUX
@@ -767,5 +767,5 @@
 
 		// do not allow Ri to exceed 0.19
-		Ri = fmin(Ri, 0.19);
+		Ri = min(Ri, 0.19);
 
 		// calculate momentum 'coefM' stability factor
@@ -947,9 +947,9 @@
 			// spectral albedos:
 			// 0.3 - 0.8um
-			IssmDouble a0 = fmin(0.98, 1.0 - 1.58 *pow(gsz[0],0.5));
+			IssmDouble a0 = min(0.98, 1.0 - 1.58 *pow(gsz[0],0.5));
 			// 0.8 - 1.5um
-			IssmDouble a1 = fmax(0.0, 0.95 - 15.4 *pow(gsz[0],0.5));
+			IssmDouble a1 = max(0.0, 0.95 - 15.4 *pow(gsz[0],0.5));
 			// 1.5 - 2.8um
-			IssmDouble a2 = fmax(0.127, 0.88 + 346.3*gsz[0] - 32.31*pow(gsz[0],0.5));
+			IssmDouble a2 = max(0.127, 0.88 + 346.3*gsz[0] - 32.31*pow(gsz[0],0.5));
 
 			// separate net shortwave radiative flux into spectral ranges
@@ -1204,5 +1204,5 @@
 		mass_diff = mass - massinit - P;
 
-		#ifndef _HAVE_ADOLC_  //avoid round operation. only check in forward mode.
+		#ifndef _HAVE_AD_  //avoid round operation. only check in forward mode.
 		mass_diff = round(mass_diff * 100.0)/100.0;
 		if (mass_diff > 0) _error_("mass not conserved in accumulation function");
@@ -1323,9 +1323,9 @@
 	// calculate temperature excess above 0 deg C
 	exsT=xNewZeroInit<IssmDouble>(n);
-	for(int i=0;i<n;i++) exsT[i]= fmax(0.0, T[i] - CtoK);        // [K] to [degC]
+	for(int i=0;i<n;i++) exsT[i]= max(0.0, T[i] - CtoK);        // [K] to [degC]
 
 	// new grid point center temperature, T [K]
 	// for(int i=0;i<n;i++) T[i]-=exsT[i];
-	for(int i=0;i<n;i++) T[i]=fmin(T[i],CtoK);
+	for(int i=0;i<n;i++) T[i]=min(T[i],CtoK);
 
 	// specify irreducible water content saturation [fraction]
@@ -1337,8 +1337,8 @@
 		if(VerboseSmb() && sid==0 && IssmComm::GetRank()==0)_printf0_("      pore water refreeze\n");
 		// calculate maximum freeze amount, maxF [kg]
-		for(int i=0;i<n;i++) maxF[i] = fmax(0.0, -((T[i] - CtoK) * m[i] * CI) / LF);
+		for(int i=0;i<n;i++) maxF[i] = max(0.0, -((T[i] - CtoK) * m[i] * CI) / LF);
 
 		// freeze pore water and change snow/ice properties
-		for(int i=0;i<n;i++) dW[i] = fmin(maxF[i], W[i]);    // freeze mass [kg]   
+		for(int i=0;i<n;i++) dW[i] = min(maxF[i], W[i]);    // freeze mass [kg]   
 		for(int i=0;i<n;i++) W[i] -= dW[i];                                            // pore water mass [kg]
 		for(int i=0;i<n;i++) m[i] += dW[i];                                            // new mass [kg]
@@ -1356,5 +1356,5 @@
 	for(int i=0;i<n;i++){
 		Wi= (dIce - d[i]) * Swi * (m[i] / d[i]);        // irreducible water content [kg]
-		exsW[i] = fmax(0.0, W[i] - Wi);                  // water "squeezed" from snow [kg]
+		exsW[i] = max(0.0, W[i] - Wi);                  // water "squeezed" from snow [kg]
 	}
 
@@ -1368,5 +1368,5 @@
 		// (maximum T of snow before entire grid cell melts is a constant
 		// LF/CI = 159.1342)
-		surpT=xNew<IssmDouble>(n); for(int i=0;i<n;i++)surpT[i] = fmax(0.0, exsT[i]- LF/CI);
+		surpT=xNew<IssmDouble>(n); for(int i=0;i<n;i++)surpT[i] = max(0.0, exsT[i]- LF/CI);
 
 		if (cellsum(surpT,n) > 0.0 + Ttol ){
@@ -1380,8 +1380,8 @@
 				T[i+1] = surpE[i]/m[i+1]/CI + T[i+1];
 
-				exsT[i+1] = fmax(0.0, T[i+1] - CtoK) + exsT[i+1];
-				T[i+1] = fmin(CtoK, T[i+1]);
-
-				surpT[i+1] = fmax(0.0, exsT[i+1] - LF/CI);
+				exsT[i+1] = max(0.0, T[i+1] - CtoK) + exsT[i+1];
+				T[i+1] = min(CtoK, T[i+1]);
+
+				surpT[i+1] = max(0.0, exsT[i+1] - LF/CI);
 				surpE[i+1] = surpT[i+1] * CI * m[i+1];
 
@@ -1394,9 +1394,9 @@
 
 		// convert temperature excess to melt [kg]
-		for(int i=0;i<n;i++) M[i] = fmin(exsT[i] * d[i] * dz[i] * CI / LF, m[i]);  // melt
+		for(int i=0;i<n;i++) M[i] = min(exsT[i] * d[i] * dz[i] * CI / LF, m[i]);  // melt
 		sumM = cellsum(M,n);                                                       // total melt [kg]
 
 		// calculate maximum refreeze amount, maxF [kg]
-		for(int i=0;i<n;i++)maxF[i] = fmax(0.0, -((T[i] - CtoK) * d[i] * dz[i] * CI)/ LF);
+		for(int i=0;i<n;i++)maxF[i] = max(0.0, -((T[i] - CtoK) * d[i] * dz[i] * CI)/ LF);
 
 		// initialize refreeze, runoff, flxDn and dW vectors [kg]
@@ -1435,6 +1435,6 @@
 				m[i] = m[i] - M[i];                     // mass after melt
 				Wi = (dIce-d[i]) * Swi * (m[i]/d[i]);    // irreducible water 
-				dW[i] = fmax(fmin(inM, Wi - W[i]),-1*W[i]);            // change in pore water
-				R[i] = fmax(0.0, inM - dW[i]);             // runoff
+				dW[i] = max(min(inM, Wi - W[i]),-1*W[i]);            // change in pore water
+				R[i] = max(0.0, inM - dW[i]);             // runoff
 				F[i] = 0.0;
 			}
@@ -1447,6 +1447,6 @@
 				m[i] = m[i] - M[i];                     // mass after melt
 				Wi = (dIce-d[i]) * Swi * (m[i]/d[i]);    // irreducible water 
-				dW[i] = fmax(fmin(inM, Wi - W[i]),-1*W[i]);              // change in pore water
-				flxDn[i+1] = fmax(0.0, inM - dW[i]);         // meltwater out
+				dW[i] = max(min(inM, Wi - W[i]),-1*W[i]);              // change in pore water
+				flxDn[i+1] = max(0.0, inM - dW[i]);         // meltwater out
 				R[i] = 0.0;
 				F[i] = 0.0;                               // no freeze 
@@ -1460,5 +1460,5 @@
 				IssmDouble dz_0 = m[i]/d[i];          
 				IssmDouble dMax = (dIce - d[i])*dz_0;              // d max = dIce
-				IssmDouble F1 = fmin(fmin(inM,dMax),maxF[i]);         // maximum refreeze               
+				IssmDouble F1 = min(min(inM,dMax),maxF[i]);         // maximum refreeze               
 				m[i] = m[i] + F1;                       // mass after refreeze
 				d[i] = m[i]/dz_0;
@@ -1466,5 +1466,5 @@
 				//-----------------------pore water-----------------------------
 				Wi = (dIce-d[i])* Swi * dz_0;            // irreducible water 
-				dW[i] = fmin(inM - F1, Wi-W[i]);         // change in pore water
+				dW[i] = min(inM - F1, Wi-W[i]);         // change in pore water
 				if (dW[i] < 0.0-Wtol && -1*dW[i]>W[i]-Wtol ){
 					dW[i]= -1*W[i];
@@ -1474,6 +1474,6 @@
 				if (dW[i] < 0.0-Wtol){                         // excess pore water
 					dMax = (dIce - d[i])*dz_0;          // maximum refreeze                                             
-					IssmDouble maxF2 = fmin(dMax, maxF[i]-F1);      // maximum refreeze
-					F2 = fmin(-1*dW[i], maxF2);            // pore water refreeze
+					IssmDouble maxF2 = min(dMax, maxF[i]-F1);      // maximum refreeze
+					F2 = min(-1*dW[i], maxF2);            // pore water refreeze
 					m[i] = m[i] + F2;                   // mass after refreeze
 					d[i] = m[i]/dz_0;
@@ -1753,5 +1753,5 @@
 
 	/*only in forward mode! avoid round in AD mode as it is not differentiable: */
-	#ifndef _HAVE_ADOLC_
+	#ifndef _HAVE_AD_
 	dm = round((mSum0 - mSum1 + mAdd)*100.0)/100.0;
 	dE = round(sumE0 - sumE1 - sumER +  addE);
@@ -1915,6 +1915,6 @@
 				c0arth = 0.07 * H;
 				c1arth = 0.03 * H;
-				M0 = fmax(1.435 - (0.151 * log(C)),0.25);
-				M1 = fmax(2.366 - (0.293 * log(C)),0.25);
+				M0 = max(1.435 - (0.151 * log(C)),0.25);
+				M1 = max(2.366 - (0.293 * log(C)),0.25);
 				c0 = M0*c0arth;
 				c1 = M1*c1arth;
@@ -1926,6 +1926,6 @@
 				c0arth = 0.07 * H;
 				c1arth = 0.03 * H;
-				M0 = fmax(1.042 - (0.0916 * log(C)),0.25);
-				M1 = fmax(1.734 - (0.2039 * log(C)),0.25);
+				M0 = max(1.042 - (0.0916 * log(C)),0.25);
+				M1 = max(1.734 - (0.2039 * log(C)),0.25);
 				c0 = M0*c0arth;
 				c1 = M1*c1arth;
@@ -2021,5 +2021,5 @@
 
 	// do not allow Ri to exceed 0.19
-	Ri = fmin(Ri, 0.19);
+	Ri = min(Ri, 0.19);
 
 	// calculate momentum 'coefM' stability factor
Index: issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp
===================================================================
--- issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp	(revision 23389)
+++ issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp	(revision 23394)
@@ -1,4 +1,4 @@
 /*!\file SurfaceMassBalancex
- * \brief: calculates SMB 
+ * \brief: calculates SMB
  */
 
@@ -105,5 +105,5 @@
 		for(v=0;v<numvertices;v++){
 			// if surface is above the ELA
-			if(s[v]>ela[v]){		
+			if(s[v]>ela[v]){
 				smb[v]=b_pos[v]*(s[v]-ela[v]);
 			}
@@ -167,5 +167,5 @@
 	//    INPUT: surface elevation (m): hd(NA)
 	//    monthly mean surface sealevel temperature (degrees C): vTempsea(NA
-	//    ,NTIME) 
+	//    ,NTIME)
 	//    monthly mean precip rate (m/yr water equivalent): vPrec(NA,NTIME)
 	//    OUTPUT: mass-balance (m/yr ice): agd(NA)
@@ -174,5 +174,5 @@
 	int    i, it, jj, itm;
 	IssmDouble DT = 0.02, sigfac, snormfac;
-	IssmDouble signorm = 5.5;      // signorm : sigma of the temperature distribution for a normal day 
+	IssmDouble signorm = 5.5;      // signorm : sigma of the temperature distribution for a normal day
 	IssmDouble siglim;       // sigma limit for the integration which is equal to 2.5 sigmanorm
 	IssmDouble signormc = signorm - 0.5;     // sigma of the temperature distribution for cloudy day
@@ -180,5 +180,5 @@
 	IssmDouble tstep, tsint, tint, tstepc;
 	int    NPDMAX = 1504, NPDCMAX = 1454;
-	//IssmDouble pdds[NPDMAX]={0}; 
+	//IssmDouble pdds[NPDMAX]={0};
 	//IssmDouble pds[NPDCMAX]={0};
 	IssmDouble pddt, pd ; // pd : snow/precip fraction, precipitation falling as snow
@@ -193,6 +193,6 @@
 	Element    *element = NULL;
 
-	pdds=xNew<IssmDouble>(NPDMAX+1); 
-	pds=xNew<IssmDouble>(NPDCMAX+1); 
+	pdds=xNew<IssmDouble>(NPDMAX+1);
+	pds=xNew<IssmDouble>(NPDCMAX+1);
 
 	// Get ismungsm parameter
@@ -216,5 +216,5 @@
 
 	if(itm >= NPDMAX) _error_("increase NPDMAX in massBalance.cpp");
-	for(it = 0; it < itm; it++){  
+	for(it = 0; it < itm; it++){
 		//    tstar = REAL(it)*DT-siglim;
 		tstar = it*DT-siglim;
@@ -262,4 +262,15 @@
 	xDelete<IssmDouble>(pds);
 }/*}}}*/
+void PositiveDegreeDaySicopolisx(FemModel* femmodel){/*{{{*/
+
+	bool isfirnwarming;
+	femmodel->parameters->FindParam(&isfirnwarming,SmbIsfirnwarmingEnum);
+
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		element->PositiveDegreeDaySicopolis(isfirnwarming);
+	}
+
+}/*}}}*/
 void SmbHenningx(FemModel* femmodel){/*{{{*/
 
@@ -346,7 +357,7 @@
 		/*Allocate all arrays*/
 		int         numvertices = element->GetNumberOfVertices();
-		IssmDouble* acc         = xNew<IssmDouble>(numvertices); 
+		IssmDouble* acc         = xNew<IssmDouble>(numvertices);
 		IssmDouble* evap        = xNew<IssmDouble>(numvertices);
-		IssmDouble* runoff      = xNew<IssmDouble>(numvertices); 
+		IssmDouble* runoff      = xNew<IssmDouble>(numvertices);
 		IssmDouble* smb         = xNew<IssmDouble>(numvertices);
 
@@ -388,5 +399,5 @@
 		int         numvertices = element->GetNumberOfVertices();
 		IssmDouble* acc         = xNew<IssmDouble>(numvertices);
-		IssmDouble* evap        = xNew<IssmDouble>(numvertices); 
+		IssmDouble* evap        = xNew<IssmDouble>(numvertices);
 		IssmDouble* melt        = xNew<IssmDouble>(numvertices);
 		IssmDouble* refreeze    = xNew<IssmDouble>(numvertices);
@@ -414,2 +425,15 @@
 
 }/*}}}*/
+void SmbGradientsComponentsx(FemModel* femmodel){/*{{{*/
+
+	// void SurfaceMassBalancex(hd,agd,ni){
+	//    INPUT parameters: ni: working size of arrays
+	//    INPUT: surface elevation (m): hd(NA)
+	//    OUTPUT: mass-balance (m/yr ice): agd(NA)
+
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		element->SmbGradCompParameterization();
+	}
+
+}/*}}}*/
Index: issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h
===================================================================
--- issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h	(revision 23389)
+++ issm/trunk/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h	(revision 23394)
@@ -1,5 +1,5 @@
 /*!\file:  SurfaceMassBalancex.h
  * \brief header file for SMB
- */ 
+ */
 
 #ifndef _SurfaceMassBalancex_H
@@ -16,11 +16,12 @@
 void Delta18opdParameterizationx(FemModel* femmodel);
 void PositiveDegreeDayx(FemModel* femmodel);
+void PositiveDegreeDaySicopolisx(FemModel* femmodel);
 void SmbHenningx(FemModel* femmodel);
 void SmbComponentsx(FemModel* femmodel);
-void SmbMeltComponentsx(FemModel* femmodel); 
-
+void SmbMeltComponentsx(FemModel* femmodel);
+void SmbGradientsComponentsx(FemModel* femmodel);
 /*GEMB: */
 void       Gembx(FemModel* femmodel);
-void       GembgridInitialize(IssmDouble** pdz, int* psize, IssmDouble zTop, IssmDouble dzTop, IssmDouble zMax, IssmDouble zY); 
+void       GembgridInitialize(IssmDouble** pdz, int* psize, IssmDouble zTop, IssmDouble dzTop, IssmDouble zMax, IssmDouble zY);
 IssmDouble Marbouty(IssmDouble T, IssmDouble d, IssmDouble dT);
 void grainGrowth(IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, IssmDouble* T,IssmDouble* dz,IssmDouble* d, IssmDouble* W,IssmDouble smb_dt,int m,int aIdx, int sid);
@@ -28,5 +29,5 @@
 void shortwave(IssmDouble** pswf, int swIdx, int aIdx, IssmDouble dsw, IssmDouble as, IssmDouble* d, IssmDouble* dz, IssmDouble* re, IssmDouble dIce, int m, int sid);
 void thermo(IssmDouble* pEC, IssmDouble** T, IssmDouble* dz, IssmDouble* d, IssmDouble* swf, IssmDouble dlw, IssmDouble Ta, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble teValue, IssmDouble Ws, IssmDouble dt0, int m, IssmDouble Vz, IssmDouble Tz, IssmDouble thermo_scaling, IssmDouble dIce, int sid);
-void accumulation(IssmDouble** pT, IssmDouble** pdz, IssmDouble** pd, IssmDouble** pW, IssmDouble** pa, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pm, int aIdx,IssmDouble Ta, IssmDouble P, IssmDouble dzMin, IssmDouble aSnow, IssmDouble dIce, int sid); 
+void accumulation(IssmDouble** pT, IssmDouble** pdz, IssmDouble** pd, IssmDouble** pW, IssmDouble** pa, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pm, int aIdx,IssmDouble Ta, IssmDouble P, IssmDouble dzMin, IssmDouble aSnow, IssmDouble dIce, int sid);
 void melt(IssmDouble* pM, IssmDouble* pR, IssmDouble* pmAdd, IssmDouble* pdz_add, IssmDouble** pT, IssmDouble** pd, IssmDouble** pdz, IssmDouble** pW, IssmDouble** pa, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pn, IssmDouble dzMin, IssmDouble zMax, IssmDouble zMin, IssmDouble zTop, IssmDouble dIce, int sid);
 void densification(IssmDouble** pd,IssmDouble** pdz, IssmDouble* T, IssmDouble* re, int denIdx, IssmDouble C, IssmDouble dt, IssmDouble Tmean, IssmDouble dIce, int m, int sid);
Index: issm/trunk/src/c/shared/Elements/PddSurfaceMassBalanceSicopolis.cpp
===================================================================
--- issm/trunk/src/c/shared/Elements/PddSurfaceMassBalanceSicopolis.cpp	(revision 23394)
+++ issm/trunk/src/c/shared/Elements/PddSurfaceMassBalanceSicopolis.cpp	(revision 23394)
@@ -0,0 +1,137 @@
+/* file:  PddSurfaceMassBlanceSicopolis.cpp
+   Calculating the surface mass balance using the adapted PDD routine from SICOPOLIS.
+ */
+
+#include "./elements.h"
+#include "../Numerics/numerics.h"
+#include "../Exceptions/exceptions.h"
+
+IssmDouble PddSurfaceMassBalanceSicopolis(IssmDouble* monthlytemperatures, IssmDouble* monthlyprec,
+				 IssmDouble* melt, IssmDouble* accu, IssmDouble* melt_star, IssmDouble* t_ampl, IssmDouble* p_ampl,
+				 IssmDouble yts, IssmDouble s, IssmDouble desfac,
+				 IssmDouble s0t, IssmDouble s0p, IssmDouble rlaps,
+				 IssmDouble rho_water,IssmDouble rho_ice){
+
+  int			imonth;				// month counter
+  IssmDouble B;					// output: surface mass balance (m/a IE), melt+accumulation
+  IssmDouble frac_solid, snowfall, rainfall, runoff; 
+  IssmDouble saccu;				// yearly surface accumulation (m/a IE)
+  IssmDouble smelt;				// yearly melt (m/a IE)
+  IssmDouble smelt_star;		// yearly ...
+  IssmDouble precip;				// total precipitation during 1 year
+  IssmDouble sconv;				//rhow_rain/rhoi / 12 months
+  IssmDouble st;					// elevation between altitude of the temp record and current altitude
+  IssmDouble sp;					// elevation between altitude of the prec record and current altitude
+  IssmDouble q;					// q is desert/elev. fact
+  IssmDouble pdd;					// pdd factor (a * degC)
+  IssmDouble tstar;				// monthly temp. after lapse rate correction (degC)
+  IssmDouble precip_star;		// monthly precip after correction (m/a IE)
+  IssmDouble beta1 = 2.73;		// 3 mm IE/(d*deg C),  ablation factor for snow per positive degree day.
+  IssmDouble beta2 = 7.28;		// 8 mm IE/(d*deg C),  ablation factor for ice per pdd (Braithwaite 1995 from tarasov 2002).
+  IssmDouble Pmax = 0.6;
+  IssmDouble inv_twelve=1./12.; 
+  
+  sconv=(rho_water/rho_ice);		//rhow_rain/rhoi
+
+  /* FIXME betas shoud be user input */
+  beta1=beta1*(0.001*365)*sconv; // (mm WE)/(d*deg C) --> (m IE)/(a*deg C)
+  beta2=beta2*(0.001*365)*sconv; // (mm WE)/(d*deg C) --> (m IE)/(a*deg C)
+
+  /* initalize fields */
+  precip=0.0;
+  tstar=0.0;
+  snowfall=0.0;
+  pdd=0.0;
+  /* seasonal loop */
+  for(imonth=0;imonth<12;imonth++){
+
+    /********* Surface temperature correction *******/    
+    st=(s-s0t)/1000.;
+
+    // FIXME rlaps ??
+	 rlaps=-6.309e-03+(-5.426e-03-(-6.309e-03))*sin((imonth+1-4)*PI/6.0)*1000.0;
+    monthlytemperatures[imonth]=monthlytemperatures[imonth]-rlaps*st;//*max(st,1e-3);
+    tstar=monthlytemperatures[imonth]+t_ampl[0];
+
+    /********* Precipitation correction *************/
+    /* Ref: Vizcaino et al 2010; DOI 10.1007/s00382-009-0591-y */
+    if(s0p<2000.0)
+      q=exp(desfac*(max(s,2000.0)-2000.0));
+	 else
+      q=exp(desfac*(max(s,2000.0)-s0p));
+
+    precip_star=q*monthlyprec[imonth]*sconv*p_ampl[0]*yts; // convert precip from m/s -> m/a
+    precip=precip+precip_star*inv_twelve;
+
+    /********* compute PDD **************************/
+    /* Ref: Calov & Greve 2005 Journal of Glaciology, Vol. 51, No. 172, 2005, Correspondence */
+	 IssmDouble s_stat=5.0;
+    IssmDouble inv_sqrt2pi =1.0/sqrt(2.0*PI);
+    IssmDouble inv_s_stat  =1.0/s_stat;
+    IssmDouble inv_sqrt2   =1.0/sqrt(2.0);
+
+	 #if !defined(_HAVE_ADOLC_)
+    pdd=pdd+(s_stat*inv_sqrt2pi*exp(-0.5*pow(tstar*inv_s_stat,2))
+				 +0.5*tstar*erfc(-tstar*inv_s_stat*inv_sqrt2))*inv_twelve;
+	 #else
+	 _error_("Cannot differentiate erfc, talk to ADOLC folks (http://functions.wolfram.com/GammaBetaErf/Erfc/20/01/)");
+	 #endif
+
+	 /*Partition of precip in solid and liquid parts, Bales et al. (2009) */
+	 IssmDouble temp_rain=7.2;		// Threshold monthly mean temperature for
+											// precipitation = 101% rain, in deg C
+	 IssmDouble temp_snow=-11.6;  // Threshold monthly mean temperature for
+											// precipitation = 100% snow, in deg C
+
+	 IssmDouble coeff1=5.4714e-01;	// Coefficients
+	 IssmDouble coeff2=-9.1603e-02;	// of
+	 IssmDouble coeff3=-3.314e-03;	// the
+	 IssmDouble coeff4= 4.66e-04;		// fifth-order
+	 IssmDouble coeff5=3.8e-05;		// polynomial
+	 IssmDouble coeff6=6.0e-07;		// fit
+   
+	 if(tstar>=temp_rain)
+	  frac_solid = 0.0;
+	 else if(tstar<=temp_snow)
+	  frac_solid = 1.0;
+	 else{ 
+		 frac_solid=coeff1+tstar*(coeff2
+					 +tstar*(coeff3+tstar*(coeff4+tstar*(coeff5+tstar*coeff6))));
+	 }
+	 
+	 snowfall=snowfall+precip_star*frac_solid*inv_twelve;
+  } 
+  /* end of seasonal loop */ 
+
+  rainfall=precip-snowfall;
+  if(snowfall<0.0) snowfall=0.0;   // correction of
+  if(rainfall<0.0) rainfall=0.0;   // negative values
+   
+  if(rainfall<=(Pmax*snowfall)){
+	  if((rainfall+beta1*pdd)<=(Pmax*snowfall)) {
+		  smelt_star = rainfall+beta1*pdd;
+		  smelt      = 0.0;
+		  runoff     = smelt;
+	  }
+	  else{
+		  smelt_star = Pmax*snowfall;
+		  smelt      = beta2*(pdd-(smelt_star-rainfall)/beta1);
+		  runoff     = smelt;
+	  }
+  } 
+  else{
+	  smelt_star = Pmax*snowfall;
+	  smelt      = beta2*pdd;
+	  runoff     = smelt+rainfall-Pmax*snowfall;
+  }
+   
+  saccu = precip;	
+
+  /* asign output*/
+  melt[0]=runoff/yts;
+  accu[0]=saccu/yts;
+  melt_star[0]=smelt_star/yts;
+  B=(saccu-runoff)/yts;
+
+  return B;
+}
Index: issm/trunk/src/c/shared/Elements/PrintArrays.cpp
===================================================================
--- issm/trunk/src/c/shared/Elements/PrintArrays.cpp	(revision 23389)
+++ issm/trunk/src/c/shared/Elements/PrintArrays.cpp	(revision 23394)
@@ -12,5 +12,5 @@
 	_printf_("\n");
 }
-#ifdef _HAVE_ADOLC_
+#ifdef _HAVE_AD_
 void printarray(IssmDouble* array,int lines,int cols){
 	_printf_("\n");
Index: issm/trunk/src/c/shared/Elements/elements.h
===================================================================
--- issm/trunk/src/c/shared/Elements/elements.h	(revision 23389)
+++ issm/trunk/src/c/shared/Elements/elements.h	(revision 23394)
@@ -24,4 +24,8 @@
 				 IssmDouble TdiffTime,IssmDouble sealevTime,IssmDouble pddsnowfac,IssmDouble pddicefac,
 				 IssmDouble rho_water, IssmDouble rho_ice);
+IssmDouble PddSurfaceMassBalanceSicopolis(IssmDouble* monthlytemperatures,  IssmDouble* monthlyprec,
+				 IssmDouble* melt, IssmDouble* accu, IssmDouble* melt_star, IssmDouble* t_ampl, IssmDouble* p_ampl,
+				 IssmDouble yts, IssmDouble s, IssmDouble desfac,IssmDouble s0t,
+				 IssmDouble s0p, IssmDouble rlaps, IssmDouble rho_water, IssmDouble rho_ice);
 void ComputeDelta18oTemperaturePrecipitation(IssmDouble Delta18oSurfacePresent, IssmDouble Delta18oSurfaceLgm, IssmDouble Delta18oSurfaceTime,
 					     IssmDouble Delta18oPresent, IssmDouble Delta18oLgm, IssmDouble Delta18oTime,
@@ -42,5 +46,5 @@
 /*Print arrays*/
 void printarray(IssmPDouble* array,int lines,int cols=1);
-#if _HAVE_ADOLC_  && !defined(_WRAPPERS_)
+#if _HAVE_AD_  && !defined(_WRAPPERS_)
 void printarray(IssmDouble* array,int lines,int cols=1);
 #endif
Index: issm/trunk/src/c/shared/Enum/EnumDefinitions.h
===================================================================
--- issm/trunk/src/c/shared/Enum/EnumDefinitions.h	(revision 23389)
+++ issm/trunk/src/c/shared/Enum/EnumDefinitions.h	(revision 23394)
@@ -53,4 +53,5 @@
 	AutodiffNumIndependentsEnum,
 	AutodiffObufsizeEnum,
+	AutodiffTapeAllocEnum,
 	AutodiffTbufsizeEnum,
 	AutodiffXpEnum,
@@ -272,4 +273,7 @@
 	SettingsSolverResidueThresholdEnum,
 	SettingsWaitonlockEnum,
+	SmbAccualtiEnum,
+	SmbAccugradEnum,
+	SmbAccurefEnum,
 	SmbAdThreshEnum,
 	SmbAIceEnum,
@@ -290,4 +294,5 @@
 	SmbIsdensificationEnum,
 	SmbIsgraingrowthEnum,
+	SmbIsfirnwarmingEnum,
 	SmbIsmeltEnum,
 	SmbIsmungsmEnum,
@@ -302,4 +307,7 @@
 	SmbPfacEnum,
 	SmbRequestedOutputsEnum,
+	SmbRunoffaltiEnum,
+	SmbRunoffgradEnum,
+	SmbRunoffrefEnum,
 	SmbSealevEnum,
 	SmbSwIdxEnum,
@@ -526,7 +534,7 @@
 	SealevelNEsaRateEnum,
 	SealevelRSLRateEnum,
-	SealevelUEsaEnum, 
+	SealevelUEsaEnum,
 	SealevelRSLEustaticRateEnum,
-	SealevelNEsaEnum, 
+	SealevelNEsaEnum,
 	SealevelUGiaEnum,
 	SealevelNGiaEnum,
@@ -577,4 +585,5 @@
 	SmbPEnum,
 	SmbPrecipitationEnum,
+	SmbPrecipitationsAnomalyEnum,
 	SmbPrecipitationsLgmEnum,
 	SmbPrecipitationsPresentdayEnum,
@@ -588,5 +597,7 @@
 	SmbSizeiniEnum,
 	SmbSmbrefEnum,
+	SmbSmbCorrEnum,
 	SmbTaEnum,
+	SmbTemperaturesAnomalyEnum,
 	SmbTemperaturesLgmEnum,
 	SmbTemperaturesPresentdayEnum,
@@ -1095,4 +1106,6 @@
 	SMBmeltcomponentsEnum,
 	SMBpddEnum,
+	SMBpddSicopolisEnum,
+	SMBgradientscomponentsEnum,
 	SmbRlapsEnum,
 	SmbRlapslgmEnum,
Index: issm/trunk/src/c/shared/Enum/EnumToStringx.cpp
===================================================================
--- issm/trunk/src/c/shared/Enum/EnumToStringx.cpp	(revision 23389)
+++ issm/trunk/src/c/shared/Enum/EnumToStringx.cpp	(revision 23394)
@@ -61,4 +61,5 @@
 		case AutodiffNumIndependentsEnum : return "AutodiffNumIndependents";
 		case AutodiffObufsizeEnum : return "AutodiffObufsize";
+		case AutodiffTapeAllocEnum : return "AutodiffTapeAlloc";
 		case AutodiffTbufsizeEnum : return "AutodiffTbufsize";
 		case AutodiffXpEnum : return "AutodiffXp";
@@ -280,4 +281,7 @@
 		case SettingsSolverResidueThresholdEnum : return "SettingsSolverResidueThreshold";
 		case SettingsWaitonlockEnum : return "SettingsWaitonlock";
+		case SmbAccualtiEnum : return "SmbAccualti";
+		case SmbAccugradEnum : return "SmbAccugrad";
+		case SmbAccurefEnum : return "SmbAccuref";
 		case SmbAdThreshEnum : return "SmbAdThresh";
 		case SmbAIceEnum : return "SmbAIce";
@@ -298,4 +302,5 @@
 		case SmbIsdensificationEnum : return "SmbIsdensification";
 		case SmbIsgraingrowthEnum : return "SmbIsgraingrowth";
+		case SmbIsfirnwarmingEnum : return "SmbIsfirnwarming";
 		case SmbIsmeltEnum : return "SmbIsmelt";
 		case SmbIsmungsmEnum : return "SmbIsmungsm";
@@ -310,4 +315,7 @@
 		case SmbPfacEnum : return "SmbPfac";
 		case SmbRequestedOutputsEnum : return "SmbRequestedOutputs";
+		case SmbRunoffaltiEnum : return "SmbRunoffalti";
+		case SmbRunoffgradEnum : return "SmbRunoffgrad";
+		case SmbRunoffrefEnum : return "SmbRunoffref";
 		case SmbSealevEnum : return "SmbSealev";
 		case SmbSwIdxEnum : return "SmbSwIdx";
@@ -583,4 +591,5 @@
 		case SmbPEnum : return "SmbP";
 		case SmbPrecipitationEnum : return "SmbPrecipitation";
+		case SmbPrecipitationsAnomalyEnum : return "SmbPrecipitationsAnomaly";
 		case SmbPrecipitationsLgmEnum : return "SmbPrecipitationsLgm";
 		case SmbPrecipitationsPresentdayEnum : return "SmbPrecipitationsPresentday";
@@ -594,5 +603,7 @@
 		case SmbSizeiniEnum : return "SmbSizeini";
 		case SmbSmbrefEnum : return "SmbSmbref";
+		case SmbSmbCorrEnum : return "SmbSmbCorr";
 		case SmbTaEnum : return "SmbTa";
+		case SmbTemperaturesAnomalyEnum : return "SmbTemperaturesAnomaly";
 		case SmbTemperaturesLgmEnum : return "SmbTemperaturesLgm";
 		case SmbTemperaturesPresentdayEnum : return "SmbTemperaturesPresentday";
@@ -1099,4 +1110,6 @@
 		case SMBmeltcomponentsEnum : return "SMBmeltcomponents";
 		case SMBpddEnum : return "SMBpdd";
+		case SMBpddSicopolisEnum : return "SMBpddSicopolis";
+		case SMBgradientscomponentsEnum : return "SMBgradientscomponents";
 		case SmbRlapsEnum : return "SmbRlaps";
 		case SmbRlapslgmEnum : return "SmbRlapslgm";
Index: issm/trunk/src/c/shared/Enum/StringToEnumx.cpp
===================================================================
--- issm/trunk/src/c/shared/Enum/StringToEnumx.cpp	(revision 23389)
+++ issm/trunk/src/c/shared/Enum/StringToEnumx.cpp	(revision 23394)
@@ -61,4 +61,5 @@
 	      else if (strcmp(name,"AutodiffNumIndependents")==0) return AutodiffNumIndependentsEnum;
 	      else if (strcmp(name,"AutodiffObufsize")==0) return AutodiffObufsizeEnum;
+	      else if (strcmp(name,"AutodiffTapeAlloc")==0) return AutodiffTapeAllocEnum;
 	      else if (strcmp(name,"AutodiffTbufsize")==0) return AutodiffTbufsizeEnum;
 	      else if (strcmp(name,"AutodiffXp")==0) return AutodiffXpEnum;
@@ -136,9 +137,9 @@
 	      else if (strcmp(name,"FrictionLaw")==0) return FrictionLawEnum;
 	      else if (strcmp(name,"FrictionPseudoplasticityExponent")==0) return FrictionPseudoplasticityExponentEnum;
-	      else if (strcmp(name,"FrictionThresholdSpeed")==0) return FrictionThresholdSpeedEnum;
          else stage=2;
    }
    if(stage==2){
-	      if (strcmp(name,"FrictionDelta")==0) return FrictionDeltaEnum;
+	      if (strcmp(name,"FrictionThresholdSpeed")==0) return FrictionThresholdSpeedEnum;
+	      else if (strcmp(name,"FrictionDelta")==0) return FrictionDeltaEnum;
 	      else if (strcmp(name,"FrictionVoidRatio")==0) return FrictionVoidRatioEnum;
 	      else if (strcmp(name,"GiaCrossSectionShape")==0) return GiaCrossSectionShapeEnum;
@@ -259,9 +260,9 @@
 	      else if (strcmp(name,"SealevelriseFluidLove")==0) return SealevelriseFluidLoveEnum;
 	      else if (strcmp(name,"SealevelriseGElastic")==0) return SealevelriseGElasticEnum;
-	      else if (strcmp(name,"SealevelriseGeodetic")==0) return SealevelriseGeodeticEnum;
          else stage=3;
    }
    if(stage==3){
-	      if (strcmp(name,"SealevelriseGeodeticRunFrequency")==0) return SealevelriseGeodeticRunFrequencyEnum;
+	      if (strcmp(name,"SealevelriseGeodetic")==0) return SealevelriseGeodeticEnum;
+	      else if (strcmp(name,"SealevelriseGeodeticRunFrequency")==0) return SealevelriseGeodeticRunFrequencyEnum;
 	      else if (strcmp(name,"SealevelriseHElastic")==0) return SealevelriseHElasticEnum;
 	      else if (strcmp(name,"SealevelriseHoriz")==0) return SealevelriseHorizEnum;
@@ -286,4 +287,7 @@
 	      else if (strcmp(name,"SettingsSolverResidueThreshold")==0) return SettingsSolverResidueThresholdEnum;
 	      else if (strcmp(name,"SettingsWaitonlock")==0) return SettingsWaitonlockEnum;
+	      else if (strcmp(name,"SmbAccualti")==0) return SmbAccualtiEnum;
+	      else if (strcmp(name,"SmbAccugrad")==0) return SmbAccugradEnum;
+	      else if (strcmp(name,"SmbAccuref")==0) return SmbAccurefEnum;
 	      else if (strcmp(name,"SmbAdThresh")==0) return SmbAdThreshEnum;
 	      else if (strcmp(name,"SmbAIce")==0) return SmbAIceEnum;
@@ -304,4 +308,5 @@
 	      else if (strcmp(name,"SmbIsdensification")==0) return SmbIsdensificationEnum;
 	      else if (strcmp(name,"SmbIsgraingrowth")==0) return SmbIsgraingrowthEnum;
+	      else if (strcmp(name,"SmbIsfirnwarming")==0) return SmbIsfirnwarmingEnum;
 	      else if (strcmp(name,"SmbIsmelt")==0) return SmbIsmeltEnum;
 	      else if (strcmp(name,"SmbIsmungsm")==0) return SmbIsmungsmEnum;
@@ -316,4 +321,7 @@
 	      else if (strcmp(name,"SmbPfac")==0) return SmbPfacEnum;
 	      else if (strcmp(name,"SmbRequestedOutputs")==0) return SmbRequestedOutputsEnum;
+	      else if (strcmp(name,"SmbRunoffalti")==0) return SmbRunoffaltiEnum;
+	      else if (strcmp(name,"SmbRunoffgrad")==0) return SmbRunoffgradEnum;
+	      else if (strcmp(name,"SmbRunoffref")==0) return SmbRunoffrefEnum;
 	      else if (strcmp(name,"SmbSealev")==0) return SmbSealevEnum;
 	      else if (strcmp(name,"SmbSwIdx")==0) return SmbSwIdxEnum;
@@ -375,5 +383,8 @@
 	      else if (strcmp(name,"TransientIsmovingfront")==0) return TransientIsmovingfrontEnum;
 	      else if (strcmp(name,"TransientIsoceancoupling")==0) return TransientIsoceancouplingEnum;
-	      else if (strcmp(name,"TransientIsslr")==0) return TransientIsslrEnum;
+         else stage=4;
+   }
+   if(stage==4){
+	      if (strcmp(name,"TransientIsslr")==0) return TransientIsslrEnum;
 	      else if (strcmp(name,"TransientIssmb")==0) return TransientIssmbEnum;
 	      else if (strcmp(name,"TransientIsstressbalance")==0) return TransientIsstressbalanceEnum;
@@ -383,8 +394,5 @@
 	      else if (strcmp(name,"Velocity")==0) return VelocityEnum;
 	      else if (strcmp(name,"WorldComm")==0) return WorldCommEnum;
-         else stage=4;
-   }
-   if(stage==4){
-	      if (strcmp(name,"ParametersEND")==0) return ParametersENDEnum;
+	      else if (strcmp(name,"ParametersEND")==0) return ParametersENDEnum;
 	      else if (strcmp(name,"InputsSTART")==0) return InputsSTARTEnum;
 	      else if (strcmp(name,"Adjoint")==0) return AdjointEnum;
@@ -498,5 +506,8 @@
 	      else if (strcmp(name,"Ice")==0) return IceEnum;
 	      else if (strcmp(name,"IceMaskNodeActivation")==0) return IceMaskNodeActivationEnum;
-	      else if (strcmp(name,"Input")==0) return InputEnum;
+         else stage=5;
+   }
+   if(stage==5){
+	      if (strcmp(name,"Input")==0) return InputEnum;
 	      else if (strcmp(name,"InversionCostFunctionsCoefficients")==0) return InversionCostFunctionsCoefficientsEnum;
 	      else if (strcmp(name,"InversionSurfaceObs")==0) return InversionSurfaceObsEnum;
@@ -506,8 +517,5 @@
 	      else if (strcmp(name,"InversionVyObs")==0) return InversionVyObsEnum;
 	      else if (strcmp(name,"LevelsetfunctionSlopeX")==0) return LevelsetfunctionSlopeXEnum;
-         else stage=5;
-   }
-   if(stage==5){
-	      if (strcmp(name,"LevelsetfunctionSlopeY")==0) return LevelsetfunctionSlopeYEnum;
+	      else if (strcmp(name,"LevelsetfunctionSlopeY")==0) return LevelsetfunctionSlopeYEnum;
 	      else if (strcmp(name,"LoadingforceX")==0) return LoadingforceXEnum;
 	      else if (strcmp(name,"LoadingforceY")==0) return LoadingforceYEnum;
@@ -595,4 +603,5 @@
 	      else if (strcmp(name,"SmbP")==0) return SmbPEnum;
 	      else if (strcmp(name,"SmbPrecipitation")==0) return SmbPrecipitationEnum;
+	      else if (strcmp(name,"SmbPrecipitationsAnomaly")==0) return SmbPrecipitationsAnomalyEnum;
 	      else if (strcmp(name,"SmbPrecipitationsLgm")==0) return SmbPrecipitationsLgmEnum;
 	      else if (strcmp(name,"SmbPrecipitationsPresentday")==0) return SmbPrecipitationsPresentdayEnum;
@@ -606,5 +615,7 @@
 	      else if (strcmp(name,"SmbSizeini")==0) return SmbSizeiniEnum;
 	      else if (strcmp(name,"SmbSmbref")==0) return SmbSmbrefEnum;
+	      else if (strcmp(name,"SmbSmbCorr")==0) return SmbSmbCorrEnum;
 	      else if (strcmp(name,"SmbTa")==0) return SmbTaEnum;
+	      else if (strcmp(name,"SmbTemperaturesAnomaly")==0) return SmbTemperaturesAnomalyEnum;
 	      else if (strcmp(name,"SmbTemperaturesLgm")==0) return SmbTemperaturesLgmEnum;
 	      else if (strcmp(name,"SmbTemperaturesPresentday")==0) return SmbTemperaturesPresentdayEnum;
@@ -618,5 +629,8 @@
 	      else if (strcmp(name,"SmbVz")==0) return SmbVzEnum;
 	      else if (strcmp(name,"SmbW")==0) return SmbWEnum;
-	      else if (strcmp(name,"SmbWini")==0) return SmbWiniEnum;
+         else stage=6;
+   }
+   if(stage==6){
+	      if (strcmp(name,"SmbWini")==0) return SmbWiniEnum;
 	      else if (strcmp(name,"SmbZMax")==0) return SmbZMaxEnum;
 	      else if (strcmp(name,"SmbZMin")==0) return SmbZMinEnum;
@@ -629,8 +643,5 @@
 	      else if (strcmp(name,"StrainRatexy")==0) return StrainRatexyEnum;
 	      else if (strcmp(name,"StrainRatexz")==0) return StrainRatexzEnum;
-         else stage=6;
-   }
-   if(stage==6){
-	      if (strcmp(name,"StrainRateyy")==0) return StrainRateyyEnum;
+	      else if (strcmp(name,"StrainRateyy")==0) return StrainRateyyEnum;
 	      else if (strcmp(name,"StrainRateyz")==0) return StrainRateyzEnum;
 	      else if (strcmp(name,"StrainRatezz")==0) return StrainRatezzEnum;
@@ -741,5 +752,8 @@
 	      else if (strcmp(name,"DatasetInput")==0) return DatasetInputEnum;
 	      else if (strcmp(name,"DataSetParam")==0) return DataSetParamEnum;
-	      else if (strcmp(name,"DefaultAnalysis")==0) return DefaultAnalysisEnum;
+         else stage=7;
+   }
+   if(stage==7){
+	      if (strcmp(name,"DefaultAnalysis")==0) return DefaultAnalysisEnum;
 	      else if (strcmp(name,"DefaultCalving")==0) return DefaultCalvingEnum;
 	      else if (strcmp(name,"DegreeOfChannelization")==0) return DegreeOfChannelizationEnum;
@@ -752,8 +766,5 @@
 	      else if (strcmp(name,"Domain3Dsurface")==0) return Domain3DsurfaceEnum;
 	      else if (strcmp(name,"DoubleArrayInput")==0) return DoubleArrayInputEnum;
-         else stage=7;
-   }
-   if(stage==7){
-	      if (strcmp(name,"DoubleExternalResult")==0) return DoubleExternalResultEnum;
+	      else if (strcmp(name,"DoubleExternalResult")==0) return DoubleExternalResultEnum;
 	      else if (strcmp(name,"DoubleInput")==0) return DoubleInputEnum;
 	      else if (strcmp(name,"DoubleMatArrayParam")==0) return DoubleMatArrayParamEnum;
@@ -864,5 +875,8 @@
 	      else if (strcmp(name,"LambdaS")==0) return LambdaSEnum;
 	      else if (strcmp(name,"LATaylorHood")==0) return LATaylorHoodEnum;
-	      else if (strcmp(name,"LevelsetAnalysis")==0) return LevelsetAnalysisEnum;
+         else stage=8;
+   }
+   if(stage==8){
+	      if (strcmp(name,"LevelsetAnalysis")==0) return LevelsetAnalysisEnum;
 	      else if (strcmp(name,"LevelsetfunctionPicard")==0) return LevelsetfunctionPicardEnum;
 	      else if (strcmp(name,"LinearFloatingMeltRate")==0) return LinearFloatingMeltRateEnum;
@@ -875,8 +889,5 @@
 	      else if (strcmp(name,"LoveKernelsImag")==0) return LoveKernelsImagEnum;
 	      else if (strcmp(name,"LoveKernelsReal")==0) return LoveKernelsRealEnum;
-         else stage=8;
-   }
-   if(stage==8){
-	      if (strcmp(name,"LoveKi")==0) return LoveKiEnum;
+	      else if (strcmp(name,"LoveKi")==0) return LoveKiEnum;
 	      else if (strcmp(name,"LoveKr")==0) return LoveKrEnum;
 	      else if (strcmp(name,"LoveLi")==0) return LoveLiEnum;
@@ -987,5 +998,8 @@
 	      else if (strcmp(name,"Outputdefinition37")==0) return Outputdefinition37Enum;
 	      else if (strcmp(name,"Outputdefinition38")==0) return Outputdefinition38Enum;
-	      else if (strcmp(name,"Outputdefinition39")==0) return Outputdefinition39Enum;
+         else stage=9;
+   }
+   if(stage==9){
+	      if (strcmp(name,"Outputdefinition39")==0) return Outputdefinition39Enum;
 	      else if (strcmp(name,"Outputdefinition3")==0) return Outputdefinition3Enum;
 	      else if (strcmp(name,"Outputdefinition40")==0) return Outputdefinition40Enum;
@@ -998,8 +1012,5 @@
 	      else if (strcmp(name,"Outputdefinition47")==0) return Outputdefinition47Enum;
 	      else if (strcmp(name,"Outputdefinition48")==0) return Outputdefinition48Enum;
-         else stage=9;
-   }
-   if(stage==9){
-	      if (strcmp(name,"Outputdefinition49")==0) return Outputdefinition49Enum;
+	      else if (strcmp(name,"Outputdefinition49")==0) return Outputdefinition49Enum;
 	      else if (strcmp(name,"Outputdefinition4")==0) return Outputdefinition4Enum;
 	      else if (strcmp(name,"Outputdefinition50")==0) return Outputdefinition50Enum;
@@ -1110,5 +1121,8 @@
 	      else if (strcmp(name,"SMBcomponents")==0) return SMBcomponentsEnum;
 	      else if (strcmp(name,"SMBd18opdd")==0) return SMBd18opddEnum;
-	      else if (strcmp(name,"SmbDesfac")==0) return SmbDesfacEnum;
+         else stage=10;
+   }
+   if(stage==10){
+	      if (strcmp(name,"SmbDesfac")==0) return SmbDesfacEnum;
 	      else if (strcmp(name,"SmbDpermil")==0) return SmbDpermilEnum;
 	      else if (strcmp(name,"SmbDzAdd")==0) return SmbDzAddEnum;
@@ -1121,9 +1135,8 @@
 	      else if (strcmp(name,"SMBhenning")==0) return SMBhenningEnum;
 	      else if (strcmp(name,"SmbMAdd")==0) return SmbMAddEnum;
-         else stage=10;
-   }
-   if(stage==10){
-	      if (strcmp(name,"SMBmeltcomponents")==0) return SMBmeltcomponentsEnum;
+	      else if (strcmp(name,"SMBmeltcomponents")==0) return SMBmeltcomponentsEnum;
 	      else if (strcmp(name,"SMBpdd")==0) return SMBpddEnum;
+	      else if (strcmp(name,"SMBpddSicopolis")==0) return SMBpddSicopolisEnum;
+	      else if (strcmp(name,"SMBgradientscomponents")==0) return SMBgradientscomponentsEnum;
 	      else if (strcmp(name,"SmbRlaps")==0) return SmbRlapsEnum;
 	      else if (strcmp(name,"SmbRlapslgm")==0) return SmbRlapslgmEnum;
Index: issm/trunk/src/c/shared/MemOps/MemOps.cpp
===================================================================
--- issm/trunk/src/c/shared/MemOps/MemOps.cpp	(revision 23389)
+++ issm/trunk/src/c/shared/MemOps/MemOps.cpp	(revision 23394)
@@ -16,5 +16,5 @@
 #if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_)
 template <> adouble*  xNew(unsigned int size, const char* const contig) {
-	if (*contig == 't')
+	if (contig[0] == 't' || contig[0] == 'c')
 		ensureContiguousLocations(size);
 
Index: issm/trunk/src/c/shared/Numerics/extrema.cpp
===================================================================
--- issm/trunk/src/c/shared/Numerics/extrema.cpp	(revision 23389)
+++ issm/trunk/src/c/shared/Numerics/extrema.cpp	(revision 23394)
@@ -11,16 +11,20 @@
 #include "./types.h"
 
+#ifndef _HAVE_CODIPACK_// already defined in codipack headers
 IssmDouble min(IssmDouble a,IssmDouble b){
 	if (a<b)return a;
 	else return b;
 }
+#endif
 int min(int a,int b){
 	if (a<b)return a;
 	else return b;
 }
+#ifndef _HAVE_CODIPACK_// already defined in codipack headers
 IssmDouble max(IssmDouble a,IssmDouble b){
 	if (a>b)return a;
 	else return b;
 }
+#endif
 int max(int a,int b){
 	if (a>b)return a;
@@ -28,5 +32,5 @@
 }
 
-#ifdef _HAVE_ADOLC_
+#ifdef _HAVE_AD_
 IssmPDouble  min(IssmPDouble a,IssmPDouble b){
 	if (a<b)return a;
Index: issm/trunk/src/c/shared/Numerics/isnan.cpp
===================================================================
--- issm/trunk/src/c/shared/Numerics/isnan.cpp	(revision 23389)
+++ issm/trunk/src/c/shared/Numerics/isnan.cpp	(revision 23394)
@@ -13,9 +13,15 @@
   return std::isnan(X.getValue());
 }
-#endif
-
-#if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_)
 template <> int xIsInf<adouble> (const adouble& X){
   return std::isinf(X.getValue());
 }
 #endif
+
+#if defined(_HAVE_CODIPACK_) && !defined(_WRAPPERS_)
+template <> int xIsNan<IssmDouble> (const IssmDouble& X){
+	  return std::isnan(X.getValue());
+}
+template <> int xIsInf<IssmDouble> (const IssmDouble& X){
+	return std::isinf(X.getValue());
+}
+#endif
Index: issm/trunk/src/c/shared/Numerics/isnan.h
===================================================================
--- issm/trunk/src/c/shared/Numerics/isnan.h	(revision 23389)
+++ issm/trunk/src/c/shared/Numerics/isnan.h	(revision 23394)
@@ -33,3 +33,9 @@
 #endif
 
+#if defined(_HAVE_CODIPACK_) && !defined(_WRAPPERS_)
+#include "./types.h"
+template <> int xIsNan<IssmDouble> (const IssmDouble& X);
+template <> int xIsInf<IssmDouble> (const IssmDouble& X);
 #endif
+
+#endif
Index: issm/trunk/src/c/shared/Numerics/numerics.h
===================================================================
--- issm/trunk/src/c/shared/Numerics/numerics.h	(revision 23389)
+++ issm/trunk/src/c/shared/Numerics/numerics.h	(revision 23394)
@@ -20,8 +20,11 @@
 #include "./OptPars.h"
 
+#if !defined(_HAVE_CODIPACK_)
+// already defined in codipack headers
 IssmDouble  min(IssmDouble a,IssmDouble b);
 IssmDouble  max(IssmDouble a,IssmDouble b);
+#endif
 
-#ifdef _HAVE_ADOLC_
+#ifdef _HAVE_AD_
 IssmPDouble  min(IssmPDouble a,IssmPDouble b);
 IssmPDouble  max(IssmPDouble a,IssmPDouble b);
Index: issm/trunk/src/c/shared/Numerics/recast.h
===================================================================
--- issm/trunk/src/c/shared/Numerics/recast.h	(revision 23389)
+++ issm/trunk/src/c/shared/Numerics/recast.h	(revision 23394)
@@ -15,5 +15,5 @@
 #endif
 
-#if !defined(_HAVE_ADOLC_) || defined(_WRAPPERS_)
+#if !defined(_HAVE_AD_) || defined(_WRAPPERS_)
 
 template<class To, class From> To reCast(const From& from) {
@@ -34,7 +34,14 @@
  * partial specialization
  */
+#ifdef _HAVE_ADOLC_
 template<class To> struct ForPartialSpecialization<To,adouble> {
     static  To reCast(const adouble& from ) { return (To) (from.getValue());}
 };
+#endif
+#ifdef _HAVE_CODIPACK_
+template<class To> struct ForPartialSpecialization<To,IssmDouble> {
+	    static  To reCast(const IssmDouble& from ) { return (To) (from.getValue());}
+};
+#endif
 
 #endif
Index: issm/trunk/src/c/shared/Numerics/types.h
===================================================================
--- issm/trunk/src/c/shared/Numerics/types.h	(revision 23389)
+++ issm/trunk/src/c/shared/Numerics/types.h	(revision 23394)
@@ -22,13 +22,18 @@
 
 #if defined(_HAVE_ADOLC_) &&  !defined(_WRAPPERS_)
+/*ADOLC typedefs*/
 #include "adolc/adolc.h"
-// for active variables
-typedef adouble IssmDouble;
-// for passive variables
-typedef double IssmPDouble;
+typedef adouble IssmDouble; /*for active variables*/
+typedef double  IssmPDouble; /*for passive variables*/
+
+#elif defined(_HAVE_CODIPACK_) && !defined(_WRAPPERS_)
+/*CoDiPack typedefs*/
+#include <codi.hpp>
+typedef codi::RealReverse IssmDouble;
+typedef double            IssmPDouble;
+
+/*Non-AD typedefs*/
 #else 
-// see above
-typedef double IssmDouble; 
-// see above
+typedef double     IssmDouble; 
 typedef IssmDouble IssmPDouble;
 #endif
Index: issm/trunk/src/c/shared/io/Marshalling/IoCodeConversions.cpp
===================================================================
--- issm/trunk/src/c/shared/io/Marshalling/IoCodeConversions.cpp	(revision 23389)
+++ issm/trunk/src/c/shared/io/Marshalling/IoCodeConversions.cpp	(revision 23394)
@@ -173,4 +173,6 @@
 		case 8: return SMBgembEnum;
 		case 9: return SMBgradientselaEnum;
+		case 10: return SMBpddSicopolisEnum;
+		case 11: return SMBgradientscomponentsEnum;
 		default: _error_("Marshalled SMB code \""<<enum_in<<"\" not supported yet");
 	}
@@ -205,5 +207,5 @@
 		case 3: return HydrologyshaktiEnum;
 		case 4: return HydrologypismEnum;
-		default: _error_("Marshalled hydrology code \""<<enum_in<<"\" not supported yet"); 
+		default: _error_("Marshalled hydrology code \""<<enum_in<<"\" not supported yet");
 	}
 }/*}}}*/
@@ -211,10 +213,10 @@
 	switch(enum_in){
 		case 1: return MatdamageiceEnum;
-		case 2: return MatestarEnum; 
+		case 2: return MatestarEnum;
 		case 3: return MaticeEnum;
 		case 4: return MatenhancediceEnum;
 		case 5: return MatlithoEnum;
 		case 6: return MaterialsEnum;
-		default: _error_("Marshalled materials code \""<<enum_in<<"\" not supported yet"); 
+		default: _error_("Marshalled materials code \""<<enum_in<<"\" not supported yet");
 	}
 }/*}}}*/
@@ -222,6 +224,6 @@
 	switch(enum_in){
 		case 1: return FixedTimesteppingEnum;
-		case 2: return AdaptiveTimesteppingEnum; 
-		default: _error_("Marshalled materials code \""<<enum_in<<"\" not supported yet"); 
+		case 2: return AdaptiveTimesteppingEnum;
+		default: _error_("Marshalled materials code \""<<enum_in<<"\" not supported yet");
 	}
 }/*}}}*/
@@ -229,6 +231,6 @@
 	switch(enum_in){
 		case 1: return AmrBamgEnum;
-		case 2: return AmrNeopzEnum; 
-		default: _error_("Marshalled AMR code \""<<enum_in<<"\" not supported yet"); 
+		case 2: return AmrNeopzEnum;
+		default: _error_("Marshalled AMR code \""<<enum_in<<"\" not supported yet");
 	}
 }/*}}}*/
Index: issm/trunk/src/c/solutionsequences/convergence.cpp
===================================================================
--- issm/trunk/src/c/solutionsequences/convergence.cpp	(revision 23389)
+++ issm/trunk/src/c/solutionsequences/convergence.cpp	(revision 23394)
@@ -7,5 +7,5 @@
 #include "../shared/shared.h"
 
-void convergence(bool* pconverged, Matrix<IssmDouble>* Kff,Vector<IssmDouble>* pf,Vector<IssmDouble>* uf,Vector<IssmDouble>* old_uf,IssmDouble eps_res,IssmDouble eps_rel,IssmDouble eps_abs){
+void convergence(bool* pconverged, Matrix<IssmDouble>* Kff,Vector<IssmDouble>* pf,Vector<IssmDouble>* uf,Vector<IssmDouble>* old_uf,IssmDouble eps_res,IssmDouble eps_rel,IssmDouble eps_abs){/*{{{*/
 
 	/*output*/
@@ -34,6 +34,9 @@
 	}
 
+
 	/*Display solver caracteristics*/
 	if (VerboseConvergence()){
+
+	
 
 		/*compute KUF = KU - F = K*U - F*/
@@ -136,3 +139,5 @@
 	/*assign output*/
 	*pconverged=converged;
-}
+}/*}}}*/
+
+
Index: issm/trunk/src/c/solutionsequences/solutionsequence_hydro_nonlinear.cpp
===================================================================
--- issm/trunk/src/c/solutionsequences/solutionsequence_hydro_nonlinear.cpp	(revision 23389)
+++ issm/trunk/src/c/solutionsequences/solutionsequence_hydro_nonlinear.cpp	(revision 23394)
@@ -190,10 +190,12 @@
 				Reduceloadx(pf,Kfs,ys); delete Kfs;
 				delete uf_epl;
+
 				femmodel->profiler->Start(SOLVER);
 				Solverx(&uf_epl,Kff,pf,uf_epl_sub_iter,df,femmodel->parameters);
 				femmodel->profiler->Stop(SOLVER);
+
 				delete Kff; delete pf; delete df;
 				delete uf_epl_sub_iter;
-				uf_epl_sub_iter=uf_epl->Duplicate();
+				uf_epl_sub_iter=uf_epl->Duplicate();_assert_(uf_epl_sub_iter);
 				uf_epl->Copy(uf_epl_sub_iter);
 				delete ug_epl;
@@ -215,6 +217,4 @@
 					_error_("   maximum number of EPL iterations (" << hydro_maxiter << ") exceeded");
 				}
-				//If there is some colapse go through sediment again
-				/* if(ThickCount<L2Count)eplconverged=true; */
 				eplcount++;
 
Index: issm/trunk/src/c/solutionsequences/solutionsequence_nonlinear.cpp
===================================================================
--- issm/trunk/src/c/solutionsequences/solutionsequence_nonlinear.cpp	(revision 23389)
+++ issm/trunk/src/c/solutionsequences/solutionsequence_nonlinear.cpp	(revision 23394)
@@ -70,4 +70,5 @@
 		Solverx(&uf, Kff, pf, old_uf, df, femmodel->parameters);
 		femmodel->profiler->Stop(SOLVER);
+	
 		Mergesolutionfromftogx(&ug, uf,ys,femmodel->nodes,femmodel->parameters);delete ys;
 
@@ -86,5 +87,5 @@
 			}
 		}
-
+		
 		/*Increase count: */
 		count++;
Index: issm/trunk/src/c/solutionsequences/solutionsequence_schurcg.cpp
===================================================================
--- issm/trunk/src/c/solutionsequences/solutionsequence_schurcg.cpp	(revision 23389)
+++ issm/trunk/src/c/solutionsequences/solutionsequence_schurcg.cpp	(revision 23394)
@@ -10,16 +10,473 @@
 #include "../analyses/analyses.h"
 
+
 #ifdef _HAVE_PETSC_
-void SchurCGSolver(Vector<IssmDouble>** puf,Mat Kff,Mat Mff,Vec pf, Vec uf0,Vec df,Parameters* parameters){/*{{{*/
+
+
+void SchurCGSolver(Vector<IssmDouble>** puf,Mat Kff,Vec pf, Vec uf0,IS isv,IS isp,Parameters* parameters){/*{{{*/
+
+	Mat                  A, B, BT;				/* Saddle point block matrices */
+	Mat						IP;						/* Preconditioner matrix */
+	Mat						IP2;
+	int                  nu, np;					/* No of. free nodes in velocity / pressure space */
+   Vec                  p,uold,unew;			/* Solution vectors for pressure / vel. */ 
+	Vec						tmpu, tmpp, rhsu,rhsp; /* temp. vectors, arbitrary RHS in vel. / pressure space */
+	Vec						gold,gnew,wold,wnew,chi,thetaold,thetanew,eta; /* CG intermediaries */
+	Vec						f1,f2;					/* RHS of the global system */
+	double					rho,gamma,tmpScalar; /* Step sizes, arbitrary double */
+	KSP						kspu,kspp;				/* KSP contexts for vel. / pressure systems*/
+	KSPConvergedReason	reason;					/* Convergence reason for troubleshooting */
+	int						its;						/* No. of iterations for troubleshooting */
+	double					initRnorm, rnorm, TOL; /* residual norms, STOP tolerance */
+	PC							pcu,pcp;					/* Preconditioner contexts pertaining the KSP contexts*/
+	PetscViewer				viewer;					/* Viewer for troubleshooting */
+	IssmPDouble				t1,t2;					/* Time measurement for bottleneck analysis */
+
+	/*STOP tolerance for the rel. residual*/
+	TOL = 0.4;
 
 	/*Initialize output*/
-	Vec uf = NULL;
-
-	_error_("not implemented yet");
+	Vector<IssmDouble>* out_uf=new Vector<IssmDouble>(uf0);
+	
+	/* Extract block matrices from the saddle point matrix */
+	/* [ A   B ] = Kff
+    * [ B^T 0 ] 
+	 *         */
+	#if (_PETSC_MAJOR_==3) && (_PETSC_MINOR_>=8)
+	MatCreateSubMatrix(Kff,isv,isv,MAT_INITIAL_MATRIX,&A);
+	MatCreateSubMatrix(Kff,isv,isp,MAT_INITIAL_MATRIX,&B);
+	MatCreateSubMatrix(Kff,isp,isv,MAT_INITIAL_MATRIX,&BT);
+	#else
+	MatGetSubMatrix(Kff,isv,isv,MAT_INITIAL_MATRIX,&A);
+	MatGetSubMatrix(Kff,isv,isp,MAT_INITIAL_MATRIX,&B);
+	MatGetSubMatrix(Kff,isp,isv,MAT_INITIAL_MATRIX,&BT);
+	#endif
+	
+	/* Extract preconditioner matrix on the pressure space*/
+	#if (_PETSC_MAJOR_==3) && (_PETSC_MINOR_>=8)
+	MatCreateSubMatrix(Kff,isp,isp,MAT_INITIAL_MATRIX,&IP);
+	#else
+	MatGetSubMatrix(Kff,isp,isp,MAT_INITIAL_MATRIX,&IP);
+	#endif
+
+	/* Get number of velocity / pressure nodes */
+	MatGetSize(B,&nu,&np);
+
+	/* Extract initial guesses for uold and pold */
+	VecCreate(IssmComm::GetComm(),&p);VecSetSizes(p,PETSC_DECIDE,np);VecSetFromOptions(p);
+	VecAssemblyBegin(p);VecAssemblyEnd(p);
+	VecCreate(IssmComm::GetComm(),&uold);VecSetSizes(uold,PETSC_DECIDE,nu);VecSetFromOptions(uold);
+	VecAssemblyBegin(uold);VecAssemblyEnd(uold);
+
+	VecGetSubVector(out_uf->pvector->vector,isv,&uold);
+	VecGetSubVector(out_uf->pvector->vector,isp,&p);
+
+
+	/* Set up intermediaries */
+	VecDuplicate(uold,&f1);VecSet(f1,0.0);
+	VecDuplicate(p,&f2);VecSet(f2,0.0);
+	VecDuplicate(uold,&tmpu);VecSet(tmpu,0.0);
+	VecDuplicate(p,&tmpp);VecSet(tmpp,0.0);
+	VecDuplicate(p,&rhsp);VecSet(rhsp,0.0);
+	VecDuplicate(uold,&rhsu);VecSet(rhsu,0.0);
+	VecDuplicate(p,&gold);VecSet(gold,0.0);
+	VecDuplicate(p,&wnew);VecSet(wnew,0.0);
+	VecDuplicate(uold,&chi);VecSet(chi,0.0);
+	VecDuplicate(p,&thetanew);VecSet(thetanew,0.0);
+	VecDuplicate(p,&thetaold);VecSet(thetaold,0.0);
+	VecDuplicate(p,&eta);VecSet(eta,0.0);
+	
+	/* Get global RHS (for each block sub-problem respectively)*/
+	VecGetSubVector(pf,isv,&f1);
+	VecGetSubVector(pf,isp,&f2);
+
+   /* ------------------------------------------------------------ */
+
+	/* Generate initial value for the velocity from the pressure */
+	/* a(u0,v) = f1(v)-b(p0,v)  i.e.  Au0 = F1-Bp0 */
+	/* u0 = u_DIR on \Gamma_DIR */
+	
+	/* Create KSP context */
+	KSPCreate(IssmComm::GetComm(),&kspu);
+	#if (_PETSC_MAJOR_==3) && (_PETSC_MINOR_>=5)
+	KSPSetOperators(kspu,A,A);
+	#else
+	KSPSetOperators(kspu,A,A,DIFFERENT_NONZERO_PATTERN);
+	#endif
+	KSPSetType(kspu,KSPCG);
+	KSPSetInitialGuessNonzero(kspu,PETSC_TRUE);
+	//KSPSetTolerances(kspu,1e-12,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
+	//KSPMonitorSet(kspu,KSPMonitorDefault,NULL,NULL);
+	KSPGetPC(kspu,&pcu);
+	PCSetType(pcu,PCSOR);
+	KSPSetUp(kspu);
+
+	
+	/* Create RHS */
+	/* RHS = F1-B * pold */
+	VecScale(p,-1.);MatMultAdd(B,p,f1,rhsu);VecScale(p,-1.);
+
+	/* Go solve Au0 = F1-Bp0*/
+	KSPSolve(kspu,rhsu,uold);
+	
+
+	/* Set up u_new */
+	VecDuplicate(uold,&unew);VecCopy(uold,unew);
+	VecAssemblyBegin(unew);VecAssemblyEnd(unew);
+
+
+
+	/* ------------------------------------------------------------- */
+
+	/*Get initial residual*/
+	/*(1/mu(x) * g0, q) = b(q,u0) - (f2,q)  i.e.  IP * g0 = BT * u0 - F2*/
+	
+	/* Create KSP context */
+	KSPCreate(IssmComm::GetComm(),&kspp);
+	#if (_PETSC_MAJOR_==3) && (_PETSC_MINOR_>=5)
+	KSPSetOperators(kspp,IP,IP);
+	#else
+	KSPSetOperators(kspp,IP,IP,DIFFERENT_NONZERO_PATTERN);
+	#endif
+	
+	/* Create RHS */
+	/* RHS = BT * uold - F2 */
+	VecScale(f2,-1.);MatMultAdd(BT,uold,f2,rhsp);VecScale(f2,-1.);
+
+	/* Set KSP & PC options */
+	KSPSetType(kspp,KSPCG);
+	KSPSetInitialGuessNonzero(kspp,PETSC_TRUE);
+	KSPGetPC(kspp,&pcp);
+	PCSetType(pcp,PCJACOBI);
+	/* Note: Systems in the pressure space are cheap, so we can afford a better tolerance */
+	KSPSetTolerances(kspp,1e-10,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
+	KSPSetUp(kspp);
+	
+	/* Go solve */
+	KSPSolve(kspp,rhsp,gold);
+	
+	/*Initial residual*/
+	VecNorm(gold,NORM_INFINITY,&initRnorm);
+	
+	/* Further setup */
+	VecDuplicate(gold,&gnew);VecCopy(gold,gnew);
+	VecAssemblyBegin(gnew);VecAssemblyEnd(gnew);
+
+
+	/* ------------------------------------------------------------ */
+
+	/*Set initial search direction*/
+	/*w0 = g0*/
+	VecDuplicate(gold,&wold);VecCopy(gold,wold);
+	VecAssemblyBegin(wold);VecAssemblyEnd(wold);
+
+	/*Realizing the step size part 1: thetam */
+	/*IP * theta = BT * uold - F2*/
+	VecScale(f2,-1.);MatMultAdd(BT,uold,f2,rhsp);VecScale(f2,-1.);
+	KSPSolve(kspp,rhsp,thetaold);
+
+
+	/* Count number of iterations */
+	int count = 0;
+
+	/* CG iteration*/
+	for(;;){
+
+		/*Realizing the step size part 2: chim */
+		/*a(chim,v) = -b(wm,v)  i.e.  A * chim = -B * wm */
+		/*chim_DIR = 0*/
+		VecScale(wold,-1.);MatMult(B,wold,rhsu);VecScale(wold,-1.);
+		KSPSolve(kspu,rhsu,chi);
+
+		/*Realizing the step size part 3: etam */
+		MatMult(BT,chi,rhsp);
+		KSPSolve(kspp,rhsp,eta);
+	
+		/* ---------------------------------------------------------- */
+
+
+		/*Set step size*/
+		/*rhom = [(wm)^T * IP^-1 * (BT * um - F2)]/[(wm)^T * IP^-1 * BT * chim]*/
+		VecDot(wold,thetaold,&rho);
+		VecDot(wold,eta,&tmpScalar);
+		rho = rho/tmpScalar;
+
+
+		/* ---------------------------------------------------------- */
+
+
+		/*Pressure update*/
+		/*p(m+1) = pm - rhom * wm*/
+		VecAXPY(p,-1.*rho,wold);
+
+
+		/*Velocity update*/
+		/*u(m+1) = um - rhom * chim*/
+		VecWAXPY(unew,-1.*rho,chi,uold);
+
+
+		/* ---------------------------------------------------------- */
+
+		/*Theta update*/
+		/*IP * theta = BT * uold - F2*/
+		VecScale(f2,-1.);MatMultAdd(BT,unew,f2,rhsp);VecScale(f2,-1.);
+		KSPSolve(kspp,rhsp,thetanew);
+
+
+		/* ---------------------------------------------------------- */
+
+		/*Residual update*/
+		/*g(m+1) = gm - rhom * BT * chim*/
+		VecWAXPY(gnew,-1.*rho,eta,gold);
+
+		/* ---------------------------------------------------------- */
+
+
+		/*BREAK if norm(g(m+0),2) < TOL or pressure space has been full searched*/
+		VecNorm(gnew,NORM_INFINITY,&rnorm);
+		if(rnorm < TOL*initRnorm) 
+		 break;
+		else if(rnorm > 100*initRnorm)
+		 _error_("Solver diverged. This shouldn't happen\n");
+		//else
+		// PetscPrintf(PETSC_COMM_WORLD,"rel. residual at step %d: %g, at TOL = %g\n",count,rnorm/initRnorm,TOL);
+	
+
+
+
+		if(count > np-1) break;
+	
+
+		/* ---------------------------------------------------------- */
+
+
+		/*Directional update*/
+		/*gamma = [g(m+1)^T * theta(m+1)]/[g(m)^T * thetam]*/
+		VecDot(gnew,thetanew,&gamma);
+		VecDot(gold,thetaold,&tmpScalar);
+		gamma = gamma/tmpScalar;
+
+		/*w(m+1) = g(m+1) + gamma * w(m)*/
+		VecWAXPY(wnew,gamma,wold,gnew);
+
+		/* Assign new to old iterates */
+		VecCopy(wnew,wold);VecCopy(gnew,gold);VecCopy(unew,uold);VecCopy(thetanew,thetaold);
+		
+		count++;
+	}
+
+
+	/* Restore pressure and velocity sol. vectors to its global form */
+	VecRestoreSubVector(out_uf->pvector->vector,isv,&unew);
+	VecRestoreSubVector(out_uf->pvector->vector,isp,&p);
 
 	/*return output pointer*/
-	Vector<IssmDouble>* out_uf=new Vector<IssmDouble>(uf);
-	VecFree(&uf);
 	*puf=out_uf;
+
+
+	/* Cleanup */
+	KSPDestroy(&kspu);KSPDestroy(&kspp);
+
+	MatDestroy(&A);MatDestroy(&B);MatDestroy(&BT);MatDestroy(&IP);
+	
+	VecDestroy(&p);VecDestroy(&uold);VecDestroy(&unew);VecDestroy(&rhsu);VecDestroy(&rhsp);
+	VecDestroy(&gold);VecDestroy(&gnew);VecDestroy(&wold);VecDestroy(&wnew);VecDestroy(&chi);
+	VecDestroy(&tmpp);VecDestroy(&tmpu);VecDestroy(&f1);VecDestroy(&f2);VecDestroy(&eta);
+	VecDestroy(&thetanew);VecDestroy(&thetaold);
+
+}/*}}}*/
+void convergence_schurcg(bool* pconverged, Matrix<IssmDouble>* Kff,Vector<IssmDouble>* pf,Vector<IssmDouble>* uf,Vector<IssmDouble>* old_uf,IssmDouble eps_res,IssmDouble eps_rel,IssmDouble eps_abs,IS isv,IS isp){/*{{{*/
+
+	/*output*/
+	bool converged=false;
+
+	/*intermediary*/
+	//Vector<IssmDouble>* KU=NULL;
+	//Vector<IssmDouble>* KUF=NULL;
+	//Vector<IssmDouble>* KUold=NULL;
+	//Vector<IssmDouble>* KUoldF=NULL;
+	Vector<IssmDouble>* duf=NULL;
+	IssmDouble ndu,nduinf,nu;
+	IssmDouble nKUF;
+	IssmDouble nKUoldF;
+	IssmDouble nF;
+	IssmDouble solver_residue,res;
+	int analysis_type;
+
+	Mat A, B, BT;
+	Vec u,p,uold,pold,f1,f2,tmp,res1,res2;
+	int n_u,n_p;
+	double rnorm1, rnorm2;
+
+
+	if(VerboseModule()) _printf0_("   checking convergence\n");
+
+	/*If uf is NULL in input, f-set is nil, model is fully constrained, therefore converged from 
+	 * the get go: */
+	if(uf->IsEmpty()){
+		*pconverged=true;
+		return;
+	}
+
+  /* Note: SchurCG also constructs the Schur preconditioner and stores it in the free block of Kff */
+  /*			[A    B]
+	* Kff =  |      |
+	*			[B^T IP]
+   * To calculate the residual, only the necessary blocks need to be extracted */
+
+		/*Extract A, B, B^T */
+		#if (_PETSC_MAJOR_==3) && (_PETSC_MINOR_>=8)
+		MatCreateSubMatrix(Kff->pmatrix->matrix,isv,isv,MAT_INITIAL_MATRIX,&A);
+		MatCreateSubMatrix(Kff->pmatrix->matrix,isv,isp,MAT_INITIAL_MATRIX,&B);
+		MatCreateSubMatrix(Kff->pmatrix->matrix,isp,isv,MAT_INITIAL_MATRIX,&BT);
+		#else
+		MatGetSubMatrix(Kff->pmatrix->matrix,isv,isv,MAT_INITIAL_MATRIX,&A);
+		MatGetSubMatrix(Kff->pmatrix->matrix,isv,isp,MAT_INITIAL_MATRIX,&B);
+		MatGetSubMatrix(Kff->pmatrix->matrix,isp,isv,MAT_INITIAL_MATRIX,&BT);
+		#endif
+	
+		/*no. of free nodes in velocity/pressure space*/
+		MatGetSize(B,&n_u,&n_p);
+
+		/*Extract values corresponding to the free velocity/pressure nodes*/
+		VecCreate(IssmComm::GetComm(),&p);VecSetSizes(p,PETSC_DECIDE,n_p);VecSetFromOptions(p);
+		VecAssemblyBegin(p);VecAssemblyEnd(p);
+		VecCreate(IssmComm::GetComm(),&u);VecSetSizes(u,PETSC_DECIDE,n_u);VecSetFromOptions(u);
+		VecAssemblyBegin(u);VecAssemblyEnd(u);
+
+		VecGetSubVector(uf->pvector->vector,isv,&u);
+		VecGetSubVector(uf->pvector->vector,isp,&p);
+		
+
+		/*Extract values of the RHS corresponding to the first/second block*/
+		VecDuplicate(u,&f1);VecSet(f1,1.0);
+		VecDuplicate(p,&f2);VecSet(f2,1.0);
+		VecGetSubVector(pf->pvector->vector,isv,&f1);
+		VecGetSubVector(pf->pvector->vector,isp,&f2);
+
+		/*Allocate intermediaries*/
+		VecDuplicate(u,&res1);VecSet(res1,1.0);
+		VecDuplicate(u,&tmp);VecSet(tmp,1.0);
+		VecDuplicate(p,&res2);VecSet(res2,1.0);
+
+
+	/*Display solver caracteristics*/
+	if (VerboseConvergence()){
+		
+		/*Calculate res1 = A*u + B*p - f1*/
+		VecScale(f1,-1.);MatMultAdd(A,u,f1,tmp);MatMultAdd(B,p,tmp,res1);VecScale(f1,-1.);
+		/*Calculate res2 = B^T * u - f2*/
+		VecScale(f2,-1.);MatMultAdd(BT,u,f2,res2);VecScale(f2,-1.);
+
+
+		/*compute norm(res1), norm(res2), norm(F) and residue*/
+		VecNorm(res1,NORM_2,&rnorm1);VecNorm(res2,NORM_2,&rnorm2);
+		nKUF=sqrt(rnorm1*rnorm1 + rnorm2*rnorm2);
+		nF=pf->Norm(NORM_TWO);
+		solver_residue=nKUF/nF;
+		_printf0_("\n" << "   solver residue: norm(KU-F)/norm(F)=" << solver_residue << "\n");
+		if(xIsNan<IssmDouble>(solver_residue)){
+			//Kff->Echo();
+		}
+
+	}
+	/*clean up*/
+	VecRestoreSubVector(uf->pvector->vector,isv,&u);
+	VecRestoreSubVector(uf->pvector->vector,isp,&p);
+	
+	/*Extract values corresponding to velocity/pressure on the old solution*/
+	VecGetSubVector(old_uf->pvector->vector,isv,&uold);
+	VecGetSubVector(old_uf->pvector->vector,isp,&pold);
+		
+
+	/*Force equilibrium (Mandatory)*/
+
+	/*Calculate res1 = A*uold + B*pold - f1*/
+	VecScale(f1,-1.);MatMultAdd(A,uold,f1,tmp);MatMultAdd(B,pold,tmp,res1);VecScale(f1,-1.);
+	/*Calculate res2 = B^T * uold - f2*/
+	VecScale(f2,-1.);MatMultAdd(BT,uold,f2,res2);VecScale(f2,-1.);
+	
+	/*compute norm(res1), norm(res2), norm(F) and residue*/
+	VecNorm(res1,NORM_2,&rnorm1);VecNorm(res2,NORM_2,&rnorm2);
+	nKUoldF=sqrt(rnorm1*rnorm1 + rnorm2*rnorm2);
+	nF=pf->Norm(NORM_TWO);
+	res=nKUoldF/nF;
+	if (xIsNan<IssmDouble>(res)){
+		_printf0_("norm nf = " << nF << "f and norm kuold = " << nKUoldF << "f\n");
+		_error_("mechanical equilibrium convergence criterion is NaN!");
+	}
+
+	MatDestroy(&A);MatDestroy(&B);MatDestroy(&BT);
+	VecRestoreSubVector(pf->pvector->vector,isv,&f1);
+	VecRestoreSubVector(pf->pvector->vector,isp,&f2);
+	VecDestroy(&res1);VecDestroy(&res2);VecDestroy(&tmp);
+	VecRestoreSubVector(old_uf->pvector->vector,isv,&uold);
+	VecRestoreSubVector(old_uf->pvector->vector,isp,&pold);
+	
+
+
+	//print
+	if(res<eps_res){
+		if(VerboseConvergence()) _printf0_(setw(50)<<left<<"   mechanical equilibrium convergence criterion"<<res*100<< " < "<<eps_res*100<<" %\n");
+		converged=true;
+	}
+	else{ 
+		if(VerboseConvergence()) _printf0_(setw(50)<<left<<"   mechanical equilibrium convergence criterion"<<res*100<<" > "<<eps_res*100<<" %\n");
+		converged=false;
+	}
+
+	/*Relative criterion (optional)*/
+	if (!xIsNan<IssmDouble>(eps_rel) || (VerboseConvergence())){
+
+		//compute norm(du)/norm(u)
+		duf=old_uf->Duplicate(); old_uf->Copy(duf); duf->AYPX(uf,-1.0);
+		ndu=duf->Norm(NORM_TWO); nu=old_uf->Norm(NORM_TWO);
+
+		if (xIsNan<IssmDouble>(ndu) || xIsNan<IssmDouble>(nu)) _error_("convergence criterion is NaN!");
+
+		//clean up
+		delete duf;
+
+		//print
+		if (!xIsNan<IssmDouble>(eps_rel)){
+			if((ndu/nu)<eps_rel){
+				if(VerboseConvergence()) _printf0_(setw(50) << left << "   Convergence criterion: norm(du)/norm(u)" << ndu/nu*100 << " < " << eps_rel*100 << " %\n");
+			}
+			else{ 
+				if(VerboseConvergence()) _printf0_(setw(50) << left << "   Convergence criterion: norm(du)/norm(u)" << ndu/nu*100 << " > " << eps_rel*100 << " %\n");
+				converged=false;
+			}
+		}
+		else _printf0_(setw(50) << left << "   Convergence criterion: norm(du)/norm(u)" << ndu/nu*100 << " %\n");
+
+	}
+
+	/*Absolute criterion (Optional) = max(du)*/
+	if (!xIsNan<IssmDouble>(eps_abs) || (VerboseConvergence())){
+
+		//compute max(du)
+		duf=old_uf->Duplicate(); old_uf->Copy(duf); duf->AYPX(uf,-1.0);
+		ndu=duf->Norm(NORM_TWO); nduinf=duf->Norm(NORM_INF);
+		if (xIsNan<IssmDouble>(ndu) || xIsNan<IssmDouble>(nu)) _error_("convergence criterion is NaN!");
+
+		//clean up
+		delete duf;
+
+		//print
+		if (!xIsNan<IssmDouble>(eps_abs)){
+			if ((nduinf)<eps_abs){
+				if(VerboseConvergence()) _printf0_(setw(50) << left << "   Convergence criterion: max(du)" << nduinf << " < " << eps_abs << "\n");
+			}
+			else{
+				if(VerboseConvergence()) _printf0_(setw(50) << left << "   Convergence criterion: max(du)" << nduinf << " > " << eps_abs << "\n");
+				converged=false;
+			}
+		}
+		else  _printf0_(setw(50) << left << "   Convergence criterion: max(du)" << nduinf << "\n");
+
+	}
+
+	/*assign output*/
+	*pconverged=converged;
 }/*}}}*/
 void solutionsequence_schurcg(FemModel* femmodel){/*{{{*/
@@ -32,8 +489,7 @@
 	Vector<IssmDouble>* old_uf = NULL;
 	Vector<IssmDouble>* pf  = NULL;
-	Vector<IssmDouble>* pf0 = NULL;
 	Vector<IssmDouble>* df  = NULL;
 	Vector<IssmDouble>* ys  = NULL;
-	Matrix<IssmDouble>* Mff = NULL;
+
 
 	/*parameters:*/
@@ -49,5 +505,5 @@
 	femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
 	femmodel->UpdateConstraintsx();
-
+	int size;
 	int  count=0;
 	bool converged=false;
@@ -69,34 +525,44 @@
 		/*Get stiffness matrix and Load vector*/
 		SystemMatricesx(&Kff,&Kfs,&pf,&df,NULL,femmodel);
-		pf0=pf->Duplicate(); pf->Copy(pf0);
 		CreateNodalConstraintsx(&ys,femmodel->nodes,configuration_type);
 		Reduceloadx(pf, Kfs, ys); delete Kfs;
 
 		/*Create mass matrix*/
-		int fsize; Kff->GetSize(&fsize,&fsize);
-		Mff=new Matrix<IssmDouble>(fsize,fsize,100,4);
 		StressbalanceAnalysis* analysis = new StressbalanceAnalysis();
 		/*Get complete stiffness matrix without penalties*/
 		for(int i=0;i<femmodel->elements->Size();i++){
 			Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
-			ElementMatrix* Me = analysis->CreatePressureMassMatrix(element);
-			if(Me) Me->AddToGlobal(Mff,NULL);
-			delete Me;
+			ElementMatrix* Ie = analysis->CreateSchurPrecondMatrix(element);
+			if(Ie) Ie->AddToGlobal(Kff,NULL);
+			delete Ie;
 		}
-		Mff->Assemble();
+		Kff->Assemble();
 		delete analysis;
+
+		/*Obtain index sets for velocity and pressure components */
+		IS isv = NULL;
+		IS isp = NULL;
+		#if _PETSC_MAJOR_==3
+			/*Make indices out of doftypes: */
+			if(!(df->pvector->vector))_error_("need doftypes for FS solver!\n");
+			DofTypesToIndexSet(&isv,&isp,df->pvector->vector,FSSolverEnum);
+		#else
+			_error_("Petsc 3.X required");
+		#endif
+
 
 		/*Solve*/
 		femmodel->profiler->Start(SOLVER);
 		_assert_(Kff->type==PetscMatType); 
+		
 		SchurCGSolver(&uf,
 					Kff->pmatrix->matrix,
-					Mff->pmatrix->matrix,
 					pf->pvector->vector,
 					old_uf->pvector->vector,
-					df->pvector->vector,
+					isv,
+					isp,
 					femmodel->parameters);
 		femmodel->profiler->Stop(SOLVER);
-		delete pf0; delete Mff;
+	
 
 		/*Merge solution from f set to g set*/
@@ -104,6 +570,7 @@
 
 		/*Check for convergence and update inputs accordingly*/
-		convergence(&converged,Kff,pf,uf,old_uf,eps_res,eps_rel,eps_abs); delete Kff; delete pf; delete df;
+		convergence_schurcg(&converged,Kff,pf,uf,old_uf,eps_res,eps_rel,eps_abs,isv,isp); delete Kff; delete pf; delete df;
 		count++;
+
 		if(count>=max_nonlinear_iterations){
 			_printf0_("   maximum number of nonlinear iterations (" << max_nonlinear_iterations << ") exceeded\n"); 
@@ -128,4 +595,5 @@
 
 }/*}}}*/
+
 #else
 void solutionsequence_schurcg(FemModel* femmodel){_error_("PETSc needs to be installed");}
Index: issm/trunk/src/c/toolkits/codipack/CoDiPackCommon.hpp
===================================================================
--- issm/trunk/src/c/toolkits/codipack/CoDiPackCommon.hpp	(revision 23394)
+++ issm/trunk/src/c/toolkits/codipack/CoDiPackCommon.hpp	(revision 23394)
@@ -0,0 +1,90 @@
+/*
+ * CoDiPackCommon.hpp
+ *
+ *  Created on: Mai 30, 2016
+ *      Author: sagebaum
+ */
+
+#ifndef _CODIPACK_COMMON_HPP_
+#define _CODIPACK_COMMON_HPP_
+
+#ifdef HAVE_CONFIG_H
+	#include <config.h>
+#else
+#error "Cannot compile without HAVE_CONFIG_H symbol! run configure first!"
+#endif
+
+#if defined(_HAVE_CODIPACK_)
+#include "codi.hpp"
+
+template<typename Real, typename Passive>
+inline void getVectorPrimal(const Real* vec, Passive* pasVec, int n) {
+  for(int i = 0; i < n; ++i) {
+    pasVec[i]=vec[i].getValue();
+  }
+}
+
+template<typename Real, typename Passive>
+inline void setVectorPrimal(Real* vec, const Passive* pasVec, int n) {
+  for(int i = 0; i < n; ++i) {
+    vec[i].value() = pasVec[i];
+  }
+}
+
+template<typename Real, typename Data>
+inline void getVectorGradData(const Real* vec, Data* dataVec, int n) {
+  for(int i = 0; i < n; ++i) {
+    dataVec[i]=vec[i].getGradientData();
+  }
+}
+
+template<typename Real, typename Passive, typename Data>
+inline void getVectorPrimalAndGradData(const Real* vec, Passive* pasVec, Data* dataVec, int n) {
+  for(int i = 0; i < n; ++i) {
+    pasVec[i]=vec[i].getValue();
+    dataVec[i]=vec[i].getGradientData();
+  }
+}
+
+template<typename Real, typename Passive, typename Data>
+inline void getPrimalAndGradData(const Real& value, Passive& pas, Data& data) {
+  pas=value.getValue();
+  data=value.getGradientData();
+}
+
+template<typename Real, typename Data>
+inline void registerVector(Real* vec, Data* dataVec, int n) {
+  typename Real::TapeType& tape = Real::getGlobalTape();
+
+  for(int i = 0; i < n; ++i) {
+    tape.registerInput(vec[i]);
+    dataVec[i]=vec[i].getGradientData();
+  }
+}
+
+template<typename Tape, typename Data, typename Adjoint>
+inline void getVectorAdjoint(Tape& tape, const Data* dataVec, Adjoint* adjVec, int n) {
+  for(int i = 0; i < n; ++i) {
+    Data index = dataVec[i];
+    adjVec[i] = tape.getGradient(index);
+    tape.gradient(index) = 0.0;
+  }
+}
+
+template<typename Tape, typename Data, typename Adjoint>
+inline void updateVectorAdjoint(Tape& tape, const Data* dataVec, const Adjoint* adjVec, int n) {
+  for(int i = 0; i < n; ++i) {
+    Data index = dataVec[i];
+    tape.gradient(index) += adjVec[i];
+  }
+}
+
+template<typename Tape, typename Data, typename Adjoint>
+inline void updateAdjoint(Tape& tape, const Data& data, const Adjoint& adj) {
+  Data index = data;
+  tape.gradient(index) += adj;
+}
+
+#endif
+
+#endif
Index: issm/trunk/src/c/toolkits/codipack/CoDiPackGlobal.h
===================================================================
--- issm/trunk/src/c/toolkits/codipack/CoDiPackGlobal.h	(revision 23394)
+++ issm/trunk/src/c/toolkits/codipack/CoDiPackGlobal.h	(revision 23394)
@@ -0,0 +1,40 @@
+/*
+ * CoDiPackGlobal.h
+ *
+ *  Created on: Jul 20, 2016
+ *      Author: a_h_ck
+ */
+
+#ifndef SRC_C_TOOLKITS_CODIPACK_CODIPACKGLOBAL_H_
+#define SRC_C_TOOLKITS_CODIPACK_CODIPACKGLOBAL_H_
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#else
+#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
+#endif
+
+#if defined(_HAVE_CODIPACK_)
+
+#include <iostream>
+#include <vector>
+
+struct CoDi_global {
+    std::vector<int> input_indices;
+    std::vector<int> output_indices;
+
+    void print(std::ostream& out) const {
+        out << "-------------------------------------\nCoDi_global:\n  in = [ ";
+        for(auto& in_index : input_indices) {
+            out << in_index << " ";
+        }
+        out << "]\n  out = [ ";
+        for(auto& out_index : output_indices) {
+            out << out_index << " ";
+        }
+        out << "]\n-------------------------------------\n";
+    }
+};
+
+#endif /* _HAVE_CODIPACK_ */
+#endif /* SRC_C_TOOLKITS_CODIPACK_CODIPACKGLOBAL_H_ */
Index: issm/trunk/src/c/toolkits/codipack/ampi_interface.cpp
===================================================================
--- issm/trunk/src/c/toolkits/codipack/ampi_interface.cpp	(revision 23394)
+++ issm/trunk/src/c/toolkits/codipack/ampi_interface.cpp	(revision 23394)
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#else
+#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
+#endif
+
+#if defined(_HAVE_ADJOINTMPI_)
+#include "externals/ampi_interface_realreverse.cpp"
+#elif defined(_HAVE_MEDIPACK_)
+#include "medi/medi.cpp"
+#else
+#error "Cannot compile without MeDiPack and AdjointMpi"
+#endif
+
Index: issm/trunk/src/c/toolkits/codipack/codipackincludes.h
===================================================================
--- issm/trunk/src/c/toolkits/codipack/codipackincludes.h	(revision 23394)
+++ issm/trunk/src/c/toolkits/codipack/codipackincludes.h	(revision 23394)
@@ -0,0 +1,11 @@
+/* \file codipackincludes.h
+ * \brief all includes for CoDiPack layer
+ */
+
+#ifndef _COIDPACK_INCLUDES_H_
+#define _COIDPACK_INCLUDES_H_
+
+#include "./CoDiPackCommon.hpp"
+#include "./CoDiPackGlobal.h"
+
+#endif
Index: issm/trunk/src/c/toolkits/gsl/DenseGslSolve.cpp
===================================================================
--- issm/trunk/src/c/toolkits/gsl/DenseGslSolve.cpp	(revision 23389)
+++ issm/trunk/src/c/toolkits/gsl/DenseGslSolve.cpp	(revision 23394)
@@ -14,4 +14,5 @@
 #include "../../classes/Params/Parameters.h"
 #include "../adolc/adolcincludes.h"
+#include "../codipack/codipackincludes.h"
 #include "./gslincludes.h"
 
@@ -251,2 +252,149 @@
 /*}}}*/
 #endif
+
+#ifdef _HAVE_CODIPACK_
+void SolverxSeq_codi_b(void* tape_in,void* data_in,void* ra) {/*{{{*/
+
+	/*recast data_in and tape*/
+	codi::DataStore* data = (codi::DataStore*)data_in;
+	//IssmDouble::TapeType& tape = (IssmDouble::TapeType&)tape_in;
+	IssmDouble::TapeType& tape = IssmDouble::getGlobalTape();
+
+  IssmDouble::Real* valueATrans;
+  IssmDouble::GradientData* indexATrans;
+  IssmDouble::GradientData* indexB;
+  IssmDouble::Real* valueX;
+  IssmDouble::GradientData* indexX;
+  int n;
+
+  data->getData(valueATrans);
+  data->getData(indexATrans);
+  data->getData(indexB);
+  data->getData(valueX);
+  data->getData(indexX);
+  data->getData(n);
+
+
+  // create the adjoint vector for x and reset the adjoint values on the tape
+  IssmDouble::GradientValue* adjX = xNew<IssmDouble::GradientValue>(n);
+  getVectorAdjoint(tape, indexX, adjX, n);
+
+  IssmDouble::GradientValue* sol  = xNew<IssmDouble::GradientValue>(n);
+  SolverxSeq(sol, valueATrans, adjX, n);
+
+  updateVectorAdjoint(tape, indexB, sol, n);
+  for(int i=0; i<n; ++i) {
+    for (int j=0; j<n; ++j) {
+      // we access the transposed matrix here because we stored the indices in a transposed way
+      updateAdjoint(tape, indexATrans[i*n+j], -sol[j]*valueX[i]);
+    }
+  }
+
+  xDelete(sol);
+  xDelete(adjX);
+}
+/*}}}*/
+void SolverxSeq_codi_delete(void* tape_in,void* data_in) {/*{{{*/
+
+	/*recast data_in*/
+	codi::DataStore* data = (codi::DataStore*)data_in;
+
+  IssmDouble::Real* valueATrans;
+  IssmDouble::GradientData* indexATrans;
+  IssmDouble::GradientData* indexB;
+  IssmDouble::Real* valueX;
+  IssmDouble::GradientData* indexX;
+  int n;
+
+  data->getData(valueATrans);
+  data->getData(indexATrans);
+  data->getData(indexB);
+  data->getData(valueX);
+  data->getData(indexX);
+  data->getData(n);
+
+  xDelete(valueATrans);
+  xDelete(indexATrans);
+  xDelete(indexB);
+  xDelete(valueX);
+  xDelete(indexX);
+}
+/*}}}*/
+void SolverxSeq(IssmDouble *X,IssmDouble *A,IssmDouble *B,int n, Parameters* parameters){/*{{{*/
+  IssmDouble::TapeType& tape = IssmDouble::getGlobalTape();
+  codi::DataStore* dataHandler = NULL;
+
+  if(tape.isActive()) {
+    dataHandler = new codi::DataStore();
+
+    // create the index vector and the double data for A and B
+    IssmDouble::Real* valueATrans = xNew<IssmDouble::Real>(n*n);
+    IssmDouble::GradientData* indexATrans = xNew<IssmDouble::GradientData>(n*n);
+
+    // read the data for matrix in a transposed fashion
+	  for (int i=0; i<n; ++i) {
+      for (int j=0; j<n; ++j) {
+        getPrimalAndGradData(A[i*n+j], valueATrans[j*n+i], indexATrans[j*n+i]);
+      }
+    }
+
+    // read the data from B (primal values are not required vor B
+    IssmDouble::GradientData* indexB = xNew<IssmDouble::GradientData>(n);
+    getVectorGradData(B, indexB, n);
+
+    dataHandler->addData(valueATrans);
+    dataHandler->addData(indexATrans);
+    dataHandler->addData(indexB);
+  }
+
+  // unpack the primal values from the matrix and the vector
+  IssmDouble::Real* valueA = xNew<IssmDouble::Real>(n*n);
+  IssmDouble::Real* valueB = xNew<IssmDouble::Real>(n);
+  // read the data from A and B
+  getVectorPrimal(A, valueA, n*n);
+  getVectorPrimal(B, valueB, n);
+
+  // create the placeholder for X and solve the system
+  IssmDouble::Real* valueX = xNew<IssmDouble::Real>(n);
+  SolverxSeq(valueX, valueA, valueB, n);
+
+  // pack the values into x
+  setVectorPrimal(X, valueX, n);
+
+  if(tape.isActive()) {
+    // create the index vector X and register x as active variables
+    IssmDouble::GradientData* indexX = xNew<IssmDouble::GradientData>(n);
+    registerVector(X, indexX, n);
+
+    dataHandler->addData(valueX);
+    dataHandler->addData(indexX);
+
+    // store other arguments
+    dataHandler->addData(n);
+
+    tape.pushExternalFunctionHandle(&SolverxSeq_codi_b, dataHandler, &SolverxSeq_codi_delete);
+  } else {
+    // if the tape is active valueX is stored in the dataHandler and deleted in the reverse sweep
+    xDelete(valueX);
+  }
+
+  xDelete(valueB);
+  xDelete(valueA);
+}
+/*}}}*/
+void DenseGslSolve(/*output*/ IssmDouble** px,/*stiffness matrix:*/ IssmDouble* Kff, int Kff_M, int Kff_N, /*right hand side load vector: */ IssmDouble* pf, int pf_M, Parameters* parameters){ /*{{{*/
+
+	/*Intermediary: */
+
+	if(Kff_N!=pf_M)_error_("Right hand side vector of size " << pf_M << ", when matrix is of size " << Kff_M << "-" << Kff_N << " !");
+	if(Kff_M!=Kff_N)_error_("Stiffness matrix should be square!");
+
+	IssmDouble *x  = xNew<IssmDouble>(Kff_N,"t");
+
+	SolverxSeq(x,Kff,pf,Kff_N,parameters);
+
+	/*allocate output pointers: */
+	*px=x;
+}
+/*}}}*/
+#endif
Index: issm/trunk/src/c/toolkits/issm/IssmToolkitUtils.cpp
===================================================================
--- issm/trunk/src/c/toolkits/issm/IssmToolkitUtils.cpp	(revision 23389)
+++ issm/trunk/src/c/toolkits/issm/IssmToolkitUtils.cpp	(revision 23394)
@@ -86,16 +86,15 @@
 int IssmSolverTypeFromToolkitOptions(void){ /*{{{*/
 
-	char* solver_type=NULL;
 	int   solver_type_enum;
-	int   num_procs=0;
 	bool  isparallel=false;
 
 	/*first, figure out if we are running in parallel: */
-	num_procs=IssmComm::GetSize();
+	int num_procs=IssmComm::GetSize();
 	if(num_procs>1)isparallel=true;
 
 	/*retrieve solver type as a string, from the Toolkits Options database, similar to what Petsc does. Actually, 
 	 *we try and stick with the Petsc vector types: */
-	solver_type=ToolkitOptions::GetToolkitOptionValue("solver_type");
+	char* solver_type=ToolkitOptions::GetToolkitOptionValue("solver_type");
+	if(!solver_type) _error_("Solver not set");
 
 	if (strcmp(solver_type,"mumps")==0){
Index: issm/trunk/src/c/toolkits/mpi/issmmpi.cpp
===================================================================
--- issm/trunk/src/c/toolkits/mpi/issmmpi.cpp	(revision 23389)
+++ issm/trunk/src/c/toolkits/mpi/issmmpi.cpp	(revision 23394)
@@ -42,5 +42,5 @@
   assert(sendcount==recvcount || sendtype==recvtype); // we handle only identical representations
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Allgather(sendbuf,
 		    sendcount,
@@ -60,5 +60,5 @@
 # endif
 #else
-# ifdef _HAVE_ADOLC_
+# ifdef _HAVE_AD_
   if (sendtype==ISSM_MPI_DOUBLE) { 
     IssmDouble* activeSendBuf=(IssmDouble*)sendbuf;
@@ -76,5 +76,5 @@
   assert(sendtype==recvtype); // we handle only identical representations
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Allgatherv(sendbuf,
 		     sendcount,
@@ -97,5 +97,5 @@
 #else
   assert(sendcount==recvcounts[0]); // we handle only identical representations 
-# ifdef _HAVE_ADOLC_
+# ifdef _HAVE_AD_
   if (sendtype==ISSM_MPI_DOUBLE) { 
     IssmDouble* activeSendBuf=(IssmDouble*)sendbuf;
@@ -113,5 +113,5 @@
   int rc=0;
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Allreduce(sendbuf,
 		    recvbuf,
@@ -129,5 +129,5 @@
 # endif
 #else
-# ifdef _HAVE_ADOLC_
+#ifdef _HAVE_AD_
   if (datatype==ISSM_MPI_DOUBLE) { 
     IssmDouble* activeSendBuf=(IssmDouble*)sendbuf;
@@ -145,5 +145,5 @@
   int rc=0;
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Barrier(comm);
 # else 
@@ -159,5 +159,5 @@
   int rc=0;
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Bcast(buffer, 
 		count,
@@ -181,5 +181,5 @@
   int rc=0;
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   assert(0); // to be implemented
 # else 
@@ -215,12 +215,19 @@
 int ISSM_MPI_Finalize(void){  /*{{{*/
 
-  int rc=0;
-#ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
-  rc=AMPI_Finalize_NT();
-# else
-  rc=MPI_Finalize();
-# endif
-#endif
+	int rc=0;
+	#ifdef _HAVE_MPI_
+		#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
+			#if defined(_HAVE_ADJOINTMPI_)
+				rc=AMPI_Finalize();
+			#elif defined(_HAVE_MEDIPACK_)
+				TOOL::finalize();
+				rc=AMPI_Finalize();
+			#else
+				rc=AMPI_Finalize_NT();
+			#endif
+		#else
+		  rc=MPI_Finalize();
+		#endif
+	#endif
   return rc;
 }/*}}}*/
@@ -230,5 +237,5 @@
   assert(sendtype==recvtype && sendcnt==recvcnt); // we handle only identical representations
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Gather(sendbuf,
 		 sendcnt,
@@ -250,5 +257,5 @@
 # endif
 #else
-# ifdef _HAVE_ADOLC_
+# ifdef _HAVE_AD_
   if (sendtype==ISSM_MPI_DOUBLE) { 
     IssmDouble* activeSendBuf=(IssmDouble*)sendbuf;
@@ -267,5 +274,5 @@
   assert(sendtype==recvtype); // we handle only identical representations
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Gatherv(sendbuf,
 		  sendcnt,
@@ -290,5 +297,5 @@
 #else
   assert(sendcnt==recvcnts[0]); // we handle only identical representations 
-# ifdef _HAVE_ADOLC_
+#ifdef _HAVE_AD_
   if (sendtype==ISSM_MPI_DOUBLE) { 
     IssmDouble* activeSendBuf=(IssmDouble*)sendbuf;
@@ -304,12 +311,19 @@
 int ISSM_MPI_Init(int *argc, char ***argv){  /*{{{*/
 
-  int rc=0;
-#ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
-  rc=AMPI_Init_NT(argc,argv);
-# else
-  rc=MPI_Init(argc,argv);
-# endif
-#endif
+	int rc=0;
+	#ifdef _HAVE_MPI_
+		#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
+			#if defined(_HAVE_ADJOINTMPI_)
+				rc=AMPI_Init(argc,argv);
+			#elif defined(_HAVE_MEDIPACK_)
+				rc=AMPI_Init(argc,argv);
+				TOOL::init();
+			#else
+				rc=AMPI_Init_NT(argc,argv);
+			#endif
+		#else
+			rc=MPI_Init(argc,argv);
+		#endif
+	#endif
   return rc;
 }/*}}}*/
@@ -318,5 +332,5 @@
   int rc=0;
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Recv(buf, 
 	       count,
@@ -324,5 +338,7 @@
 	       source,
 	       tag,
+			 #if !defined(_HAVE_ADJOINTMPI_) && !defined(_HAVE_MEDIPACK_)
 	       AMPI_FROM_SEND, // as long as there are no other variants
+			 #endif
 	       comm,
 	       status);
@@ -347,5 +363,5 @@
   int rc=0;
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Reduce(sendbuf,
 		 recvbuf,
@@ -365,5 +381,5 @@
 # endif
 #else
-# ifdef _HAVE_ADOLC_
+# ifdef _HAVE_AD_
   if (datatype==ISSM_MPI_DOUBLE) { 
     IssmDouble* activeSendBuf=(IssmDouble*)sendbuf;
@@ -382,5 +398,5 @@
   assert(sendtype==recvtype && sendcnt==recvcnt); // we handle only identical representations
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Scatter(sendbuf,
 		  sendcnt,
@@ -402,5 +418,5 @@
 # endif
 #else
-# ifdef _HAVE_ADOLC_
+# ifdef _HAVE_AD_
   if (sendtype==ISSM_MPI_DOUBLE) { 
     IssmDouble* activeSendBuf=(IssmDouble*)sendbuf;
@@ -419,5 +435,5 @@
   assert(sendtype==recvtype); // we handle only identical representations
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Scatterv(sendbuf,
 		   sendcnts,
@@ -442,5 +458,5 @@
 #else
   assert(sendcnts[0]==recvcnt); // we handle only identical representations 
-# ifdef _HAVE_ADOLC_
+# ifdef _HAVE_AD_
   if (sendtype==ISSM_MPI_DOUBLE) { 
     IssmDouble* activeSendBuf=(IssmDouble*)(sendbuf)+displs[0];
@@ -458,5 +474,5 @@
   int rc=0;
 #ifdef _HAVE_MPI_
-# ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
   rc=AMPI_Send(buf, 
 	       count,
@@ -464,5 +480,7 @@
 	       dest,
 	       tag,
+			 #if !defined(_HAVE_ADJOINTMPI_) && !defined(_HAVE_MEDIPACK_)
 	       AMPI_TO_RECV, // as long as there are no other variants
+			 #endif
 	       comm);
 # else
@@ -492,4 +510,6 @@
 #ifdef _HAVE_ADOLC_
   ensureContiguousLocations(aSize);
+#else
+  fprintf(stderr, "*** Codipack ISSM_MPI_ContiguousInAdolc()\n");
 #endif
 }/*}}}*/
@@ -498,5 +518,5 @@
 int rc=0;
 #ifdef _HAVE_MPI_
-#ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
 rc=MPI_Comm_split(comm, color, key, newcomm);
 #else
@@ -512,5 +532,5 @@
 	int rc=0;
 #ifdef _HAVE_MPI_
-#ifdef _HAVE_AMPI_
+#if defined(_HAVE_AMPI_) &&  !defined(_WRAPPERS_)
 	rc=MPI_Intercomm_create(comm,local_leader,peer_comm,remote_leader,tag,newintercomm);
 #else
Index: issm/trunk/src/c/toolkits/mpi/issmmpi.h
===================================================================
--- issm/trunk/src/c/toolkits/mpi/issmmpi.h	(revision 23389)
+++ issm/trunk/src/c/toolkits/mpi/issmmpi.h	(revision 23394)
@@ -16,8 +16,27 @@
 #include "../../shared/Numerics/types.h"
 
-#ifdef _HAVE_MPI_
+#if defined(_HAVE_MPI_)
 	/*Include header files: {{{*/
-	#ifdef _HAVE_AMPI_
-		#include <ampi/ampi.h>
+	#if defined(_HAVE_AMPI_) && !defined(_WRAPPERS_)
+		#if defined(_HAVE_ADJOINTMPI_)
+			#include <ampi_tape.hpp>
+
+		#elif defined(_HAVE_MEDIPACK_)
+			#include "medi/medi.hpp"
+			using namespace medi;
+			#include "medi/codiMediPackTypes.hpp"
+			#if defined(_HAVE_CODIPACK_)
+			#define TOOL CoDiPackTool<IssmDouble>
+			#define AMPI_ADOUBLE TOOL::MPI_TYPE
+			#elif defined(_HAVE_ADOLC_)
+			#include "adolc/medipacksupport.h"
+			#define TOOL AdolcTool
+			#else
+			#error "don't know about AD tool"
+			#endif
+
+		#else
+			#include <ampi/ampi.h>
+		#endif
 	#elif  _HAVE_PETSC_MPI_ // Petsc now hides there MPI header. It can be reached through Petsc.
 		#include <petsc.h>
@@ -27,31 +46,58 @@
 	/*}}}*/
 	/*MPI defines: *{{{*/
+
 	// types
+	#if defined(_HAVE_MEDIPACK_) && !defined(_WRAPPERS_)
+	typedef AMPI_Comm             ISSM_MPI_Comm;
+	typedef AMPI_Datatype         ISSM_MPI_Datatype;
+	typedef AMPI_Op               ISSM_MPI_Op;
+	typedef AMPI_Status           ISSM_MPI_Status;
+	#else
 	typedef MPI_Comm             ISSM_MPI_Comm;
 	typedef MPI_Datatype         ISSM_MPI_Datatype;
 	typedef MPI_Op               ISSM_MPI_Op;
 	typedef MPI_Status           ISSM_MPI_Status;
+	#endif
 
-	// data types
-	#define ISSM_MPI_CHAR       MPI_CHAR
-	#ifdef _HAVE_AMPI_
-		#define ISSM_MPI_DOUBLE    AMPI_ADOUBLE // corresponds to IssmDouble
-	#else 
-		#define ISSM_MPI_DOUBLE    MPI_DOUBLE  // corresponds to IssmDouble 
+	#if defined(_HAVE_MEDIPACK_) && !defined(_WRAPPERS_)
+	#define ISSM_MPI_CHAR       AMPI_CHAR
+	#define ISSM_MPI_DOUBLE     AMPI_ADOUBLE // corresponds to IssmDouble
+	#define ISSM_MPI_PDOUBLE    AMPI_DOUBLE  // corresponds to IssmPDouble
+	#define ISSM_MPI_INT        AMPI_INT
+	
+	// operations
+	#define ISSM_MPI_MAX        AMPI_MAX
+	#define ISSM_MPI_MIN        AMPI_MIN
+	#define ISSM_MPI_PROD       AMPI_PROD
+	#define ISSM_MPI_SUM        AMPI_SUM
+	
+	// others
+	#define ISSM_MPI_COMM_WORLD    AMPI_COMM_WORLD
+	#define ISSM_MPI_STATUS_IGNORE AMPI_STATUS_IGNORE
+	#define ISSM_MPI_ANY_TAG       AMPI_ANY_TAG
+	#define ISSM_MPI_ANY_SOURCE    AMPI_ANY_SOURCE
+
+	#else
+		#if defined(_HAVE_AMPI_) && !defined(_WRAPPERS_)
+			#define ISSM_MPI_DOUBLE    AMPI_ADOUBLE
+		#else 
+			#define ISSM_MPI_DOUBLE    MPI_DOUBLE
+		#endif
+		#define ISSM_MPI_PDOUBLE    MPI_DOUBLE
+		#define ISSM_MPI_INT        MPI_INT
+		#define ISSM_MPI_CHAR       MPI_CHAR
+
+		// operations
+		#define ISSM_MPI_MAX        MPI_MAX
+		#define ISSM_MPI_MIN        MPI_MIN
+		#define ISSM_MPI_PROD       MPI_PROD
+		#define ISSM_MPI_SUM        MPI_SUM
+
+		// others
+		#define ISSM_MPI_COMM_WORLD    MPI_COMM_WORLD
+		#define ISSM_MPI_STATUS_IGNORE MPI_STATUS_IGNORE
+		#define ISSM_MPI_ANY_TAG       MPI_ANY_TAG
+		#define ISSM_MPI_ANY_SOURCE    MPI_ANY_SOURCE
 	#endif
-	#define ISSM_MPI_PDOUBLE    MPI_DOUBLE  // corresponds to IssmPDouble
-	#define ISSM_MPI_INT        MPI_INT
-
-	// operations
-	#define ISSM_MPI_MAX        MPI_MAX
-	#define ISSM_MPI_MIN        MPI_MIN
-	#define ISSM_MPI_PROD       MPI_PROD
-	#define ISSM_MPI_SUM        MPI_SUM
-
-	// others
-	#define ISSM_MPI_COMM_WORLD    MPI_COMM_WORLD
-	#define ISSM_MPI_STATUS_IGNORE MPI_STATUS_IGNORE
-	#define ISSM_MPI_ANY_TAG       MPI_ANY_TAG
-	#define ISSM_MPI_ANY_SOURCE    MPI_ANY_SOURCE
 
     /*other include files: */
@@ -90,5 +136,5 @@
 template <class T> ISSM_MPI_Datatype TypeToMPIType(){assert(false);};
 template <> inline ISSM_MPI_Datatype TypeToMPIType<IssmDouble>(){return ISSM_MPI_DOUBLE;};
-#if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_) 
+#if defined(_HAVE_AD_) && !defined(_WRAPPERS_) 
 template <> inline ISSM_MPI_Datatype TypeToMPIType<IssmPDouble>(){return ISSM_MPI_PDOUBLE;};
 #endif
Index: issm/trunk/src/c/toolkits/mumps/MumpsSolve.cpp
===================================================================
--- issm/trunk/src/c/toolkits/mumps/MumpsSolve.cpp	(revision 23389)
+++ issm/trunk/src/c/toolkits/mumps/MumpsSolve.cpp	(revision 23394)
@@ -18,4 +18,5 @@
 #include "../mpi/issmmpi.h"
 #include "../adolc/adolcincludes.h"
+#include "../codipack/codipackincludes.h"
 #include "../issm/SparseRow.h"
 #include "./mumpsincludes.h"
@@ -25,4 +26,9 @@
 
 void MumpsInit(DMUMPS_STRUC_C &theMumpsStruc){ 
+	theMumpsStruc.n = 0;
+	theMumpsStruc.nz = 0;
+	theMumpsStruc.a = NULL;
+	theMumpsStruc.jcn = NULL;
+	theMumpsStruc.irn = NULL;
 	theMumpsStruc.par          = 1;  
 	theMumpsStruc.sym          = 0;
@@ -98,5 +104,5 @@
 }
 
-#ifdef _HAVE_ADOLC_
+#ifdef _HAVE_AD_
 // prototype for active variant
 void MumpsSolve(int n,
@@ -354,6 +360,5 @@
 
 #ifdef _HAVE_ADOLC_
-
-int mumpsSolveEDF(int iArrLength, int* iArr, int /* ignored */, IssmPDouble* dp_x, int /* ignored */, IssmPDouble* dp_y) {
+int mumpsSolveEDF(int iArrLength, int* iArr, int /* ignored */, IssmPDouble* dp_x, int /* ignored */, IssmPDouble* dp_y){/*{{{*/
   // unpack parameters
   int n=iArr[0];
@@ -381,7 +386,6 @@
   xDelete(local_irn);
   return 0;
-}
-
-void MumpsSolve(int n,int nnz,int local_nnz,int* irn_loc,int* jcn_loc,IssmDouble *a_loc,IssmDouble *rhs,Parameters* parameters){
+}/*}}}*/
+void MumpsSolve(int n,int nnz,int local_nnz,int* irn_loc,int* jcn_loc,IssmDouble *a_loc,IssmDouble *rhs,Parameters* parameters){/*{{{*/
   int packedDimsSparseArrLength=1+1+1+local_nnz+local_nnz;
   int *packedDimsSparseArr=xNew<int>(packedDimsSparseArrLength);
@@ -425,10 +429,6 @@
   xDelete(pack_A_rhs);
   xDelete(packedDimsSparseArr);
-}
-
-int fos_reverse_mumpsSolveEDF(int iArrLength, int* iArr, 
-			      int m, IssmPDouble *dp_U,
-			      int nPlusNz, IssmPDouble *dp_Z,
-			      IssmPDouble *dp_x, IssmPDouble *dp_y) {
+}/*}}}*/
+int fos_reverse_mumpsSolveEDF(int iArrLength, int* iArr, int m, IssmPDouble *dp_U, int nPlusNz, IssmPDouble *dp_Z, IssmPDouble *dp_x, IssmPDouble *dp_y) {/*{{{*/
   // unpack parameters
   int n=iArr[0];
@@ -481,5 +481,168 @@
   xDelete(local_irn);
   return 3;
-}
-
-#endif
+}/*}}}*/
+#endif
+
+#ifdef _HAVE_CODIPACK_
+void MumpsSolve_codi_b(void* tape_in,void* data_in,void* ra) {/*{{{*/
+
+	/*recast data_in and tape*/
+  codi::DataStore* data = (codi::DataStore*)data_in;
+  //IssmDouble::TapeType& tape = (IssmDouble::TapeType&)tape_in;
+  IssmDouble::TapeType& tape = IssmDouble::getGlobalTape();
+
+
+  IssmDouble::Real* valueATrans;
+  IssmDouble::GradientData* indexATrans;
+  int* irnATrans;
+  int* jcnATrans;
+  IssmDouble::GradientData* indexB;
+  IssmDouble::Real* valueX;
+  IssmDouble::GradientData* indexX;
+  int n;
+  int nnz;
+  int local_nnz;
+  Parameters* parameters;
+
+  data->getData(valueATrans);
+  data->getData(indexATrans);
+  data->getData(irnATrans);
+  data->getData(jcnATrans);
+  data->getData(indexB);
+  data->getData(valueX);
+  data->getData(indexX);
+  data->getData(n);
+  data->getData(nnz);
+  data->getData(local_nnz);
+  data->getData(parameters);
+
+  // create the adjoint vector for x and reset the adjoint values on the tape
+  IssmDouble::GradientValue* adjX = xNew<IssmDouble::GradientValue>(n);
+  getVectorAdjoint(tape, indexX, adjX, n);
+
+  MumpsSolve(n, nnz, local_nnz, irnATrans, jcnATrans, valueATrans, adjX, parameters);
+  // adjX contains now the solution
+
+  updateVectorAdjoint(tape, indexB, adjX, n);
+
+  // bcast dp_y (the solution of the forward system)
+  ISSM_MPI_Bcast(valueX,n,ISSM_MPI_PDOUBLE,0,IssmComm::GetComm());
+  // bcast the adjoint of the right-hand-side, i.e. this solution
+  ISSM_MPI_Bcast(adjX,n,ISSM_MPI_PDOUBLE,0,IssmComm::GetComm());
+
+  for(int i=0; i<local_nnz; ++i) {
+    // we access the transposed matrix here because we stored the indices in a transposed way
+    // -1 is substracted because jcn and irn are stored with fortran indexing
+    updateAdjoint(tape, indexATrans[i], -adjX[jcnATrans[i]-1]*valueX[irnATrans[i]-1]);
+  }
+
+  xDelete(adjX);
+}
+/*}}}*/
+void MumpsSolve_codi_delete(void* tape_in,void* data_in) {/*{{{*/
+
+	/*recast data_in*/
+	codi::DataStore* data = (codi::DataStore*)data_in;
+
+  IssmDouble::Real* valueATrans;
+  IssmDouble::GradientData* indexATrans;
+  int* irnATrans;
+  int* jcnATrans;
+  IssmDouble::GradientData* indexB;
+  IssmDouble::Real* valueX;
+  IssmDouble::GradientData* indexX;
+  int n;
+  int nnz;
+  int local_nnz;
+  Parameters* parameters;
+
+  data->getData(valueATrans);
+  data->getData(indexATrans);
+  data->getData(irnATrans);
+  data->getData(jcnATrans);
+  data->getData(indexB);
+  data->getData(valueX);
+  data->getData(indexX);
+  data->getData(n);
+  data->getData(nnz);
+  data->getData(local_nnz);
+  data->getData(parameters);
+
+  xDelete(valueATrans);
+  xDelete(indexATrans);
+  xDelete(irnATrans);
+  xDelete(jcnATrans);
+  xDelete(indexB);
+  xDelete(valueX);
+  xDelete(indexX);
+}
+/*}}}*/
+void MumpsSolve(int n,int nnz,int local_nnz,int* irn_loc,int* jcn_loc,IssmDouble *a_loc,IssmDouble *rhs,Parameters* parameters){/*{{{*/
+  IssmDouble::TapeType& tape = IssmDouble::getGlobalTape();
+  codi::DataStore* dataHandler = NULL;
+
+  if(tape.isActive()) {
+    dataHandler = new codi::DataStore();
+
+    // create the index and double vector for the matrix
+    IssmDouble::Real* valueATrans = xNew<IssmDouble::Real>(local_nnz);
+    IssmDouble::GradientData* indexATrans = xNew<IssmDouble::GradientData>(local_nnz);
+    int* irnATrans = xNew<int>(local_nnz);
+    int* jcnATrans = xNew<int>(local_nnz);
+
+    // read the data for the matrix A in a transposed fashion
+	  for (int i=0; i<local_nnz; ++i) {
+        getPrimalAndGradData(a_loc[i], valueATrans[i], indexATrans[i]);
+        irnATrans[i]=jcn_loc[i];  // transposed store
+        jcnATrans[i]=irn_loc[i];  // transposed store
+    }
+
+    // create the index vector for a (primal values are not needed for a)
+    IssmDouble::GradientData* indexB = xNew<IssmDouble::GradientData>(n);
+    getVectorGradData(rhs, indexB, n);
+
+    dataHandler->addData(valueATrans);
+    dataHandler->addData(indexATrans);
+    dataHandler->addData(irnATrans);
+    dataHandler->addData(jcnATrans);
+    dataHandler->addData(indexB);
+  }
+
+  // unpack the primal values from the matrix and the vector
+  IssmDouble::Real* valueA = xNew<IssmDouble::Real>(local_nnz);
+  IssmDouble::Real* valueB = xNew<IssmDouble::Real>(n);
+  // read the data from A and B
+  getVectorPrimal(a_loc, valueA, local_nnz);
+  getVectorPrimal(rhs, valueB, n);
+
+  MumpsSolve(n, nnz, local_nnz, irn_loc, jcn_loc, valueA, valueB, parameters);
+  // valueB contains now the solution
+
+  // pack the values into rhs
+  setVectorPrimal(rhs, valueB, n);
+
+  if(tape.isActive()) {
+    // create the index vector X and register x as active variables
+    IssmDouble::GradientData* indexX = xNew<IssmDouble::GradientData>(n);
+    registerVector(rhs, indexX, n);
+
+    dataHandler->addData(valueB); // contains the values from x
+    dataHandler->addData(indexX);
+
+    // store other arguments
+    dataHandler->addData(n);
+    dataHandler->addData(nnz);
+    dataHandler->addData(local_nnz);
+    dataHandler->addData(parameters); // we assume here that parameters is still intact when the reverse run is called
+
+	 //tape.pushExternalFunction(&MumpsSolve_codi_b, dataHandler, &MumpsSolve_codi_delete);
+    tape.pushExternalFunctionHandle(&MumpsSolve_codi_b,(void*)dataHandler, &MumpsSolve_codi_delete);
+  } else {
+    // if the tape is active valueB is stored in the dataHandler and deleted in the reverse sweep
+    xDelete(valueB);
+  }
+
+  xDelete(valueA);
+}
+/*}}}*/
+#endif
Index: issm/trunk/src/c/toolkits/petsc/objects/PetscMat.cpp
===================================================================
--- issm/trunk/src/c/toolkits/petsc/objects/PetscMat.cpp	(revision 23389)
+++ issm/trunk/src/c/toolkits/petsc/objects/PetscMat.cpp	(revision 23394)
@@ -21,5 +21,5 @@
 PetscMat::PetscMat(){/*{{{*/
 	this->matrix=NULL;
-	#ifdef _HAVE_ADOLC_
+	#ifdef _HAVE_AD_
 	this->amatrix=NULL;
 	#endif
Index: issm/trunk/src/c/toolkits/petsc/objects/PetscMat.h
===================================================================
--- issm/trunk/src/c/toolkits/petsc/objects/PetscMat.h	(revision 23389)
+++ issm/trunk/src/c/toolkits/petsc/objects/PetscMat.h	(revision 23394)
@@ -27,5 +27,5 @@
 		Mat matrix;
 
-		#ifdef _HAVE_ADOLC_
+		#ifdef _HAVE_AD_
 		IssmDouble* amatrix;
 		#endif
Index: issm/trunk/src/c/toolkits/petsc/objects/PetscSolver.cpp
===================================================================
--- issm/trunk/src/c/toolkits/petsc/objects/PetscSolver.cpp	(revision 23389)
+++ issm/trunk/src/c/toolkits/petsc/objects/PetscSolver.cpp	(revision 23394)
@@ -15,4 +15,5 @@
 #include "../../../shared/io/Comm/IssmComm.h"
 #include "../../../shared/Enum/Enum.h"
+#include "../../../shared/io/Print/Print.h"
 
 void	PetscSolve(PetscVec** puf, PetscMat* Kff, PetscVec* pf, PetscVec* uf0,PetscVec* df, Parameters* parameters){ /*{{{*/
@@ -156,4 +157,5 @@
 	KSPGetIterationNumber(ksp,&iteration_number);
 	if (iteration_number<0) _error_("Solver diverged at iteration number: " << -iteration_number);
+	if (VerboseSolver())  _printf0_("Petsc: "<< iteration_number << " KSP iterations\n"); 
 
 	/*Free resources:*/
Index: issm/trunk/src/c/toolkits/petsc/objects/PetscVec.cpp
===================================================================
--- issm/trunk/src/c/toolkits/petsc/objects/PetscVec.cpp	(revision 23389)
+++ issm/trunk/src/c/toolkits/petsc/objects/PetscVec.cpp	(revision 23394)
@@ -21,5 +21,5 @@
 PetscVec::PetscVec(){/*{{{*/
 	this->vector=NULL;
-	#ifdef _HAVE_ADOLC_
+	#ifdef _HAVE_AD_
 	this->avector=NULL;
 	#endif
Index: issm/trunk/src/c/toolkits/petsc/objects/PetscVec.h
===================================================================
--- issm/trunk/src/c/toolkits/petsc/objects/PetscVec.h	(revision 23389)
+++ issm/trunk/src/c/toolkits/petsc/objects/PetscVec.h	(revision 23394)
@@ -25,5 +25,5 @@
 		Vec vector;
 
-		#ifdef _HAVE_ADOLC_
+		#ifdef _HAVE_AD_
 		IssmDouble* avector;
 		#endif
Index: issm/trunk/src/c/toolkits/toolkits.h
===================================================================
--- issm/trunk/src/c/toolkits/toolkits.h	(revision 23389)
+++ issm/trunk/src/c/toolkits/toolkits.h	(revision 23394)
@@ -30,4 +30,8 @@
 #endif
 
+#ifdef _HAVE_CODIPACK_
+#include "./codipack/codipackincludes.h"
+#endif
+
 #ifdef _HAVE_TRIANGLE_
 #include "./triangle/triangleincludes.h"
Index: issm/trunk/src/m/classes/SMBgradientscomponents.m
===================================================================
--- issm/trunk/src/m/classes/SMBgradientscomponents.m	(revision 23394)
+++ issm/trunk/src/m/classes/SMBgradientscomponents.m	(revision 23394)
@@ -0,0 +1,90 @@
+%SMBgradientscomponents Class definition
+%
+%   Usage:
+%      SMBgradientscomponents=SMBgradientscomponents();
+
+classdef SMBgradientscomponents
+	properties (SetAccess=public)
+		accuref					  = NaN;
+		accualti				  = NaN;
+		accugrad				  = NaN;
+		runoffref				  = NaN;
+		runoffalti			  = NaN;
+		runoffgrad			  = NaN;
+		requested_outputs = {};
+	end
+	methods
+		function self=SMBgradientscomponents(varargin) % {{{
+			switch nargin
+				case 0
+					self=setdefaultparameters(self);
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+
+		function self = extrude(self,md) % {{{
+
+		%Nothing for now
+
+		end % }}}
+		function list = defaultoutputs(self,md) % {{{
+			list = {'runoff'};
+		end % }}}
+		function self = initialize(self,md) % {{{
+
+		%Nothing done for now
+
+		end % }}}
+		function self = setdefaultparameters(self) % {{{
+
+		%Nothing for now
+
+		end % }}}
+		function	md=checkconsistency(self,md,solution,analyses) % {{{
+			if ismember('MasstransportAnalysis',analyses),
+				md = checkfield(md,'fieldname','smb.accuref','timeseries',1,'NaN',1,'Inf',1);
+				md = checkfield(md,'fieldname','smb.accualti','numel',1,'NaN',1,'Inf',1);
+				md = checkfield(md,'fieldname','smb.accugrad','numel',1,'NaN',1,'Inf',1);
+				md = checkfield(md,'fieldname','smb.runoffref','timeseries',1,'NaN',1,'Inf',1);
+				md = checkfield(md,'fieldname','smb.runoffalti','numel',1,'NaN',1,'Inf',1);
+				md = checkfield(md,'fieldname','smb.runoffgrad','numel',1,'NaN',1,'Inf',1);
+			end
+			md = checkfield(md,'fieldname','masstransport.requested_outputs','stringrow',1);
+		end % }}}
+
+		function disp(self) % {{{
+			disp(sprintf('   surface forcings parameters:'));
+			disp(sprintf('\n   SMB gradients components parameters:'));
+			fielddisplay(self,'accuref',' reference value of the accumulation');
+			fielddisplay(self,'accualti',' Altitude at which the accumulation is equal to the reference value');
+			fielddisplay(self,'accugrad',' Gradient of the variation of the accumulation (0 for uniform accumulation)');
+			fielddisplay(self,'runoffref',' reference value of the runoff m w.e. y-1 (temperature times ddf)');
+			fielddisplay(self,'runoffalti',' Altitude at which the runoff is equal to the reference value');
+			fielddisplay(self,'runoffgrad',' Gradient of the variation of the runoff (0 for uniform runoff) m w.e. m-1 y-1 (lpase rate times ddf)');
+			fielddisplay(self,'requested_outputs','additional outputs requested');
+
+		end % }}}
+		function marshall(self,prefix,md,fid)    % {{{
+
+			WriteData(fid,prefix,'name','md.smb.model','data',11,'format','Integer');
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','accuref','format','DoubleMat','mattype',1,'timeserieslength',2,'yts',md.constants.yts,'scale',1./md.constants.yts);
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','accualti','format','Double');
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','accugrad','format','Double','scale',1./md.constants.yts);
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','runoffref','format','DoubleMat','mattype',1,'timeserieslength',2,'yts',md.constants.yts,'scale',1./md.constants.yts);
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','runoffalti','format','Double');
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','runoffgrad', ...
+								'format','Double','scale',1./md.constants.yts);
+
+			%process requested outputs
+			outputs = self.requested_outputs;
+			pos  = find(ismember(outputs,'default'));
+			if ~isempty(pos),
+				outputs(pos) = [];                         %remove 'default' from outputs
+				outputs      = [outputs defaultoutputs(self,md)]; %add defaults
+			end
+			WriteData(fid,prefix,'data',outputs,'name','md.smb.requested_outputs','format','StringArray');
+
+		end % }}}
+	end
+end
Index: issm/trunk/src/m/classes/SMBgradientscomponents.py
===================================================================
--- issm/trunk/src/m/classes/SMBgradientscomponents.py	(revision 23394)
+++ issm/trunk/src/m/classes/SMBgradientscomponents.py	(revision 23394)
@@ -0,0 +1,78 @@
+from fielddisplay import fielddisplay
+from checkfield import checkfield
+from WriteData import WriteData
+from project3d import project3d
+
+class SMBgradientscomponents(object):
+	"""
+	SMBgradients Class definition
+
+	   Usage:
+	      SMBgradients=SMBgradientscomponents();
+	For now it has accumulation, runoff ans retention which could be aither refreezing and/or evaporation
+	"""
+
+	def __init__(self): # {{{
+		self.accuref					 = float('NaN')
+		self.accualti					 = float('NaN')
+		self.accugrad					 = float('NaN')
+		self.runoffref				 = float('NaN')
+		self.runoffalti				 = float('NaN')
+		self.runoffgrad				 = float('NaN')
+		self.requested_outputs = ['default']
+		#}}}
+	def __repr__(self): # {{{
+		string="   surface forcings parameters:"
+		string="%s\n%s"%(string,fielddisplay(self,'accuref',' reference value of the accumulation'))
+		string="%s\n%s"%(string,fielddisplay(self,'accualti',' Altitude at which the accumulation is equal to the reference value'))
+		string="%s\n%s"%(string,fielddisplay(self,'accugrad',' Gradient of the variation of the accumulation (0 for uniform accumulation)'))
+		string="%s\n%s"%(string,fielddisplay(self,'runoffref',' reference value of the runoff m w.e. y-1 (temperature times ddf)'))
+		string="%s\n%s"%(string,fielddisplay(self,'runoffalti',' Altitude at which the runoff is equal to the reference value'))
+		string="%s\n%s"%(string,fielddisplay(self,'runoffgrad',' Gradient of the variation of the runoff (0 for uniform runoff) m w.e. m-1 y-1 (lpase rate times ddf)'))
+		string="%s\n%s"%(string,fielddisplay(self,'requested_outputs','additional outputs requested'))
+
+		return string
+		#}}}
+	def extrude(self,md): # {{{
+		#Nothing for now
+		return self
+	#}}}
+	def defaultoutputs(self,md): # {{{
+		return ['SmbMassBalance','SmbRunoff']
+	#}}}
+	def initialize(self,md): # {{{
+		#Nothing for now
+		return self
+	#}}}
+	def checkconsistency(self,md,solution,analyses):    # {{{
+		if 'MasstransportAnalysis' in analyses:
+			md = checkfield(md,'fieldname','smb.accuref','singletimeseries',1,'NaN',1,'Inf',1)
+			md = checkfield(md,'fieldname','smb.accualti','numel',[1],'NaN',1,'Inf',1)
+			md = checkfield(md,'fieldname','smb.accugrad','numel',[1],'NaN',1,'Inf',1)
+			md = checkfield(md,'fieldname','smb.runoffref','singletimeseries',1,'NaN',1,'Inf',1)
+			md = checkfield(md,'fieldname','smb.runoffalti','numel',[1],'NaN',1,'Inf',1)
+			md = checkfield(md,'fieldname','smb.runoffgrad','numel',[1],'NaN',1,'Inf',1)
+		md = checkfield(md,'fieldname','masstransport.requested_outputs','stringrow',1)
+		return md
+	# }}}
+	def marshall(self,prefix,md,fid):    # {{{
+
+		yts=md.constants.yts
+
+		WriteData(fid,prefix,'name','md.smb.model','data',11,'format','Integer')
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','accuref','format','DoubleMat','mattype',1,'timeserieslength',2,'yts',md.constants.yts,'scale',1./md.constants.yts)
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','accualti','format','Double')
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','accugrad','format','Double','scale',1./md.constants.yts)
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','runoffref','format','DoubleMat','mattype',1,'timeserieslength',2,'yts',md.constants.yts,'scale',1./md.constants.yts)
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','runoffalti','format','Double')
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','runoffgrad','format','Double','scale',1./md.constants.yts)
+
+		#process requested outputs
+		outputs = self.requested_outputs
+		indices = [i for i, x in enumerate(outputs) if x == 'default']
+		if len(indices) > 0:
+			outputscopy=outputs[0:max(0,indices[0]-1)]+self.defaultoutputs(md)+outputs[indices[0]+1:]
+			outputs    =outputscopy
+		WriteData(fid,prefix,'data',outputs,'name','md.smb.requested_outputs','format','StringArray')
+
+	# }}}
Index: issm/trunk/src/m/classes/SMBpddSicopolis.m
===================================================================
--- issm/trunk/src/m/classes/SMBpddSicopolis.m	(revision 23394)
+++ issm/trunk/src/m/classes/SMBpddSicopolis.m	(revision 23394)
@@ -0,0 +1,133 @@
+%SMBpddSicopolis Class definition
+%
+%   Usage:
+%      SMBpddSicopolis=SMBpddSicopolis();
+
+classdef SMBpddSicopolis
+	properties (SetAccess=public) 
+		precipitation					= NaN;
+		monthlytemperatures			= NaN;
+		temperature_anomaly			= NaN;
+		precipitation_anomaly		= NaN;
+		smb_corr							= NaN;
+		desfac							= 0;
+		s0p								= NaN;
+		s0t								= NaN;
+		rlaps								= 0;
+		isfirnwarming					= 0;
+		requested_outputs				= {};
+	end
+	methods
+		function self = SMBpddSicopolis(varargin) % {{{
+			switch nargin
+				case 0
+					self=setdefaultparameters(self);
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+		function self = extrude(self,md) % {{{
+			self.precipitation=project3d(md,'vector',self.precipitation,'type','node');
+			self.monthlytemperatures=project3d(md,'vector',self.monthlytemperatures,'type','node');
+			self.temperature_anomaly=project3d(md,'vector',self.temperature_anomaly,'type','node');
+			self.precipitation_anomaly=project3d(md,'vector',self.precipitation_anomaly,'type','node');
+			self.smb_corr=project3d(md,'vector',self.smb_corr,'type','node');
+			self.s0p=project3d(md,'vector',self.s0p,'type','node');
+			self.s0t=project3d(md,'vector',self.s0t,'type','node');
+
+		end % }}}
+		function list = defaultoutputs(self,md) % {{{
+			list = {''};
+		end % }}}
+		function self = initialize(self,md) % {{{
+                    
+			if isnan(self.s0p),
+				self.s0p=zeros(md.mesh.numberofvertices,1);
+				disp('      no SMBpddSicopolis.s0p specified: values set as zero');
+			end
+			if isnan(self.s0t),
+				self.s0t=zeros(md.mesh.numberofvertices,1);
+				disp('      no SMBpddSicopolis.s0t specified: values set as zero');
+			end
+			if isnan(self.temperature_anomaly),
+				self.temperature_anomaly=zeros(md.mesh.numberofvertices,1);
+				disp('      no SMBpddSicopolis.temperature_anomaly specified: values set as zero');
+			end
+			if isnan(self.precipitation_anomaly),
+				self.precipitation_anomaly=ones(md.mesh.numberofvertices,1);
+				disp('      no SMBpddSicopolis.precipitation_anomaly specified: values set as ones');
+			end
+			if isnan(self.smb_corr),
+				self.smb_corr=zeros(md.mesh.numberofvertices,1);
+				disp('      no SMBpddSicopolis.smb_corr specified: values set as zero');
+			end
+
+		end % }}}
+		function self = setdefaultparameters(self) % {{{
+
+		  self.isfirnwarming		= 1;
+		  self.desfac				= -log(2.0)/1000;
+		  self.rlaps				= 7.4;
+                  
+		end % }}}
+		function md = checkconsistency(self,md,solution,analyses) % {{{
+
+			if (strcmp(solution,'TransientSolution') & md.transient.issmb == 0), return; end
+
+			if ismember('MasstransportAnalysis',analyses),
+				md = checkfield(md,'fieldname','smb.desfac','<=',1,'numel',1);
+				md = checkfield(md,'fieldname','smb.s0p','>=',0,'NaN',1,'Inf',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','smb.s0t','>=',0,'NaN',1,'Inf',1,'size',[md.mesh.numberofvertices 1]);
+				md = checkfield(md,'fieldname','smb.rlaps','>=',0,'numel',1);
+				md = checkfield(md,'fieldname','smb.monthlytemperatures','timeseries',1,'NaN',1,'Inf',1,'size',[md.mesh.numberofvertices+1 12]);
+				md = checkfield(md,'fieldname','smb.precipitation','timeseries',1,'NaN',1,'Inf',1,'size',[md.mesh.numberofvertices+1 12]);
+			end
+			md = checkfield(md,'fieldname','smb.requested_outputs','stringrow',1);
+			
+		end % }}}
+		function disp(self) % {{{
+			disp(sprintf('   surface forcings parameters:'));
+
+			disp(sprintf('\n   SICOPOLIS PDD scheme (Calov & Greve, 2005) :'));
+			fielddisplay(self,'monthlytemperatures','monthly surface temperatures [K]');
+			fielddisplay(self,'precipitation','monthly surface precipitation [m/yr water eq]');
+			fielddisplay(self,'temperature_anomaly','anomaly to monthly reference temperature (additive; [K])');
+			fielddisplay(self,'precipitation_anomaly','anomaly to monthly precipitation (multiplicative, e.g. q=q0*exp(0.070458*DeltaT) after Huybrechts (2002)); [no unit])');
+			fielddisplay(self,'smb_corr','correction of smb after PDD call [m/a]');
+			fielddisplay(self,'s0p','should be set to elevation from precip source (between 0 and a few 1000s m, default is 0) [m]');
+			fielddisplay(self,'s0t','should be set to elevation from temperature source (between 0 and a few 1000s m, default is 0) [m]');
+			fielddisplay(self,'rlaps','present day lapse rate (default is 7.4 degree/km)');
+			fielddisplay(self,'desfac','desertification elevation factor (default is -log(2.0)/1000)');
+			fielddisplay(self,'isfirnwarming','is firnwarming (Reeh 1991) activated (0 or 1, default is 1)');
+			fielddisplay(self,'requested_outputs','additional outputs requested (TemperaturePDD, SmbAccumulation, SmbMelt)');
+		end % }}}
+		function marshall(self,prefix,md,fid) % {{{
+
+			yts=md.constants.yts;
+
+			WriteData(fid,prefix,'name','md.smb.model','data',10,'format','Integer');
+
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','isfirnwarming','format','Boolean');
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','desfac','format','Double');
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','s0p','format','DoubleMat','mattype',1);
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','s0t','format','DoubleMat','mattype',1);
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','rlaps','format','Double');
+
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','monthlytemperatures','format','DoubleMat','mattype',1,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts);
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','precipitation','format','DoubleMat','mattype',1,'scale',1./yts,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts);
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','temperature_anomaly','format','DoubleMat','mattype',1,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts);
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','precipitation_anomaly','format','DoubleMat','mattype',1,'scale',1./yts,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts);
+			WriteData(fid,prefix,'object',self,'class','smb','fieldname','smb_corr','format','DoubleMat','mattype',1,'scale',1./yts,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts);
+
+			%process requested outputs
+			outputs = self.requested_outputs;
+			pos  = find(ismember(outputs,'default'));
+			if ~isempty(pos),
+				outputs(pos) = [];                         %remove 'default' from outputs
+				outputs      = [outputs defaultoutputs(self,md)]; %add defaults
+			end
+			WriteData(fid,prefix,'data',outputs,'name','md.smb.requested_outputs','format','StringArray');
+
+		end % }}}
+	end
+end
Index: issm/trunk/src/m/classes/SMBpddSicopolis.py
===================================================================
--- issm/trunk/src/m/classes/SMBpddSicopolis.py	(revision 23394)
+++ issm/trunk/src/m/classes/SMBpddSicopolis.py	(revision 23394)
@@ -0,0 +1,153 @@
+import numpy as np
+from fielddisplay import fielddisplay
+from checkfield import checkfield
+from WriteData import WriteData
+from project3d import project3d
+from MatlabFuncs import *
+from helpers import *
+
+class SMBpddSicopolis(object):
+	"""
+	SMBpddSicopolis Class definition
+
+	Usage:
+		SMBpddSicopolis=SMBpddSicopolis()
+"""
+
+	def __init__(self): # {{{
+		self.precipitation			= float('NaN')
+		self.monthlytemperatures		= float('NaN')
+		self.temperature_anomaly		= float('NaN')
+		self.precipitation_anomaly		= float('NaN')
+		self.smb_corr				= float('NaN')
+		self.desfac				= 0
+		self.s0p				= float('NaN')
+		self.s0t				= float('NaN')
+		self.rlaps				= 0
+		self.isfirnwarming			= 0
+		self.requested_outputs			= []
+		
+		self.setdefaultparameters()
+	# }}}
+	
+	@staticmethod
+	def SMBpddSicopolis(*args): # {{{
+		nargin = len(args)
+
+		if nargin == 0:
+			return SMBpddSicopolis()
+		else:
+			raise RuntimeError('SMBpddSicopolis: constructor not supported')
+	# }}}
+
+	def extrude(self,md): # {{{
+		self.precipitation = project3d(md,'vector',self.precipitation,'type','node')
+		self.monthlytemperatures = project3d(md,'vector',self.monthlytemperatures,'type','node')
+		self.temperature_anomaly = project3d(md,'vector',self.temperature_anomaly,'type','node')
+		self.precipitation_anomaly = project3d(md,'vector',self.precipitation_anomaly,'type','node')
+		self.smb_corr = project3d(md,'vector',self.smb_corr,'type','node')
+		self.s0p = project3d(md,'vector',self.s0p,'type','node')
+		self.s0t = project3d(md,'vector',self.s0t,'type','node')
+	# }}}
+
+	def defaultoutputs(self,md): # {{{
+		l = ['']
+		return l
+	# }}}
+
+	def initialize(self,md): # {{{
+            
+		if np.isnan(self.s0p):
+			self.s0p = np.zeros((md.mesh.numberofvertices,))
+			print '      no SMBpddSicopolis.s0p specified: values set as zero'
+		
+		if np.isnan(self.s0t):
+			self.s0t = np.zeros((md.mesh.numberofvertices,))
+			print '      no SMBpddSicopolis.s0t specified: values set as zero'
+		
+		if np.isnan(self.temperature_anomaly):
+			self.temperature_anomaly = np.zeros((md.mesh.numberofvertices,))
+			print '      no SMBpddSicopolis.temperature_anomaly specified: values set as zero'
+		
+		if np.isnan(self.precipitation_anomaly):
+			self.precipitation_anomaly = np.ones((md.mesh.numberofvertices,))
+			print '      no SMBpddSicopolis.precipitation_anomaly specified: values set as ones'
+		
+		if np.isnan(self.smb_corr):
+			self.smb_corr = np.zeros((md.mesh.numberofvertices,))
+			print '      no SMBpddSicopolis.smb_corr specified: values set as zero'
+	# }}}
+
+	def setdefaultparameters(self): # {{{
+
+	  self.isfirnwarming	= 1
+	  self.desfac		= -np.log(2.0)/1000
+	  self.rlaps		= 7.4
+          
+	# }}}
+
+	def checkconsistency(self,md,solution,analyses): # {{{
+
+		if (strcmp(solution,'TransientSolution') and md.transient.issmb == 0):
+			return 
+
+		if 'MasstransportAnalysis' in analyses:
+			md = checkfield(md,'fieldname','smb.desfac','<=',1,'numel',1)
+			md = checkfield(md,'fieldname','smb.s0p','>=',0,'NaN',1,'Inf',1,'size',[md.mesh.numberofvertices,1])
+			md = checkfield(md,'fieldname','smb.s0t','>=',0,'NaN',1,'Inf',1,'size',[md.mesh.numberofvertices,1])
+			md = checkfield(md,'fieldname','smb.rlaps','>=',0,'numel',1)
+			md = checkfield(md,'fieldname','smb.monthlytemperatures','timeseries',1,'NaN',1,'Inf',1,'size',[md.mesh.numberofvertices+1,12])
+			md = checkfield(md,'fieldname','smb.precipitation','timeseries',1,'NaN',1,'Inf',1,'size',[md.mesh.numberofvertices+1,12])
+		
+		md = checkfield(md,'fieldname','smb.requested_outputs','stringrow',1)
+		
+		return md
+	# }}}
+
+	def __repr__(self): # {{{
+		string = '   surface forcings parameters:'
+		string += '\n   SICOPOLIS PDD scheme (Calov & Greve, 2005) :'
+
+		string = "%s\n%s"%(string,fielddisplay(self,'monthlytemperatures','monthly surface temperatures [K]'))
+		string = "%s\n%s"%(string,fielddisplay(self,'precipitation','monthly surface precipitation [m/yr water eq]'))
+		string = "%s\n%s"%(string,fielddisplay(self,'temperature_anomaly','anomaly to monthly reference temperature (additive [K])'))
+		string = "%s\n%s"%(string,fielddisplay(self,'precipitation_anomaly','anomaly to monthly precipitation (multiplicative, e.g. q=q0*exp(0.070458*DeltaT) after Huybrechts (2002)) [no unit])'))
+		string = "%s\n%s"%(string,fielddisplay(self,'smb_corr','correction of smb after PDD call [m/a]'))
+		string = "%s\n%s"%(string,fielddisplay(self,'s0p','should be set to elevation from precip source (between 0 and a few 1000s m, default is 0) [m]'))
+		string = "%s\n%s"%(string,fielddisplay(self,'s0t','should be set to elevation from temperature source (between 0 and a few 1000s m, default is 0) [m]'))
+		string = "%s\n%s"%(string,fielddisplay(self,'rlaps','present day lapse rate (default is 7.4 degree/km)'))
+		string = "%s\n%s"%(string,fielddisplay(self,'desfac','desertification elevation factor (default is -log(2.0)/1000)'))
+		string = "%s\n%s"%(string,fielddisplay(self,'isfirnwarming','is firnwarming (Reeh 1991) activated (0 or 1, default is 1)'))
+		string = "%s\n%s"%(string,fielddisplay(self,'requested_outputs','additional outputs requested (TemperaturePDD, SmbAccumulation, SmbMelt)'))
+	# }}}
+
+	def marshall(self,prefix,md,fid): # {{{
+
+		yts=md.constants.yts
+
+		WriteData(fid,prefix,'name','md.smb.model','data',10,'format','Integer')
+
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','isfirnwarming','format','Boolean')
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','desfac','format','Double')
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','s0p','format','DoubleMat','mattype',1)
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','s0t','format','DoubleMat','mattype',1)
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','rlaps','format','Double')
+
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','monthlytemperatures','format','DoubleMat','mattype',1,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts)
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','precipitation','format','DoubleMat','mattype',1,'scale',1./yts,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts)
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','temperature_anomaly','format','DoubleMat','mattype',1,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts)
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','precipitation_anomaly','format','DoubleMat','mattype',1,'scale',1./yts,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts)
+		WriteData(fid,prefix,'object',self,'class','smb','fieldname','smb_corr','format','DoubleMat','mattype',1,'scale',1./yts,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts)
+
+		#process requested outputs
+		outputs = self.requested_outputs
+		pos  = np.where('default' in outputs)
+		if not isempty(pos):
+			outputs[pos] = []                         #remove 'default' from outputs
+			outputs      = [outputs,defaultoutputs(self,md)] #add defaults
+		
+		WriteData(fid,prefix,'data',outputs,'name','md.smb.requested_outputs','format','StringArray')
+
+	# }}}
+	
+
Index: issm/trunk/src/m/classes/autodiff.js
===================================================================
--- issm/trunk/src/m/classes/autodiff.js	(revision 23389)
+++ issm/trunk/src/m/classes/autodiff.js	(revision 23394)
@@ -14,4 +14,5 @@
 		this.gcTriggerRatio=2.0;
 		this.gcTriggerMaxSize=65536;
+		this.tapeAlloc    = 15000000;
 
 	}// }}}
@@ -29,4 +30,5 @@
 		fielddisplay(this,'gcTriggerRatio','free location block sorting/consolidation triggered if the ratio between allocated and used locations exceeds gcTriggerRatio');
 		fielddisplay(this,'gcTriggerMaxSize','free location block sorting/consolidation triggered if the allocated locations exceed gcTriggerMaxSize');
+		fielddisplay(this,'tapeAlloc','Iteration count of a priori memory allocation of the AD tape');
 
 	}// }}}
@@ -49,4 +51,5 @@
 			checkfield(md,'fieldname','autodiff.gcTriggerRatio','>=',0);
 			checkfield(md,'fieldname','autodiff.gcTriggerMaxSize','>=',65536);
+			checkfield(md,'fieldname','autodiff.tapeAlloc','>=',0);
 
 			//go through our dependents and independents and check consistency: 
@@ -79,4 +82,5 @@
 			WriteData(fid,prefix,'object',this,'fieldname','gcTriggerRatio','format','Double');
 			WriteData(fid,prefix,'object',this,'fieldname','gcTriggerMaxSize','format','Double');
+			WriteData(fid,prefix,'object',this,'fieldname','tapeAlloc','format','Integer');
 			//}}}
 			//process dependent variables {{{
@@ -216,4 +220,5 @@
 			this.gcTriggerRatio=NullFix(this.gcTriggerRatio,NaN);
 			this.gcTriggerMaxSize=NullFix(this.gcTriggerMaxSize,NaN);
+			this.tapeAlloc=NullFix(this.tapeAlloc,NaN);
 		}//}}}
 	//properties 
@@ -229,4 +234,5 @@
 	this.gcTriggerRatio = NaN;
 	this.gcTriggerMaxSize = NaN;
+	this.tapeAlloc = NaN;
 
 	this.setdefaultparameters();
Index: issm/trunk/src/m/classes/autodiff.m
===================================================================
--- issm/trunk/src/m/classes/autodiff.m	(revision 23389)
+++ issm/trunk/src/m/classes/autodiff.m	(revision 23394)
@@ -17,4 +17,5 @@
 		gcTriggerRatio = NaN;
 		gcTriggerMaxSize = NaN;
+		tapeAlloc = NaN;
 		end
 		%}}}
@@ -35,4 +36,5 @@
 		self.gcTriggerRatio=2.0;
 		self.gcTriggerMaxSize=65536;
+		self.tapeAlloc    = 15000000;
 		end % }}}
 		function md = checkconsistency(self,md,solution,analyses) % {{{
@@ -51,4 +53,5 @@
 			md = checkfield(md,'fieldname','autodiff.gcTriggerRatio','>=',0);
 			md = checkfield(md,'fieldname','autodiff.gcTriggerMaxSize','>=',65536);
+			md = checkfield(md,'fieldname','autodiff.tapeAlloc','>=',0);
 
 			%go through our dependents and independents and check consistency: 
@@ -75,4 +78,5 @@
 			fielddisplay(self,'gcTriggerRatio','free location block sorting/consolidation triggered if the ratio between allocated and used locations exceeds gcTriggerRatio');
 			fielddisplay(self,'gcTriggerMaxSize','free location block sorting/consolidation triggered if the allocated locations exceed gcTriggerMaxSize');
+			fielddisplay(self,'tapeAlloc','Iteration count of a priori memory allocation of the AD tape');
 		end % }}}
 		function marshall(self,prefix,md,fid) % {{{
@@ -95,4 +99,5 @@
 			WriteData(fid,prefix,'object',self,'fieldname','gcTriggerRatio','format','Double');
 			WriteData(fid,prefix,'object',self,'fieldname','gcTriggerMaxSize','format','Double');
+			WriteData(fid,prefix,'object',self,'fieldname','tapeAlloc','format','Integer');
 			%}}}
 			%process dependent variables {{{
Index: issm/trunk/src/m/classes/autodiff.py
===================================================================
--- issm/trunk/src/m/classes/autodiff.py	(revision 23389)
+++ issm/trunk/src/m/classes/autodiff.py	(revision 23394)
@@ -25,4 +25,5 @@
 		self.gcTriggerMaxSize     = float('NaN')
 		self.gcTriggerRatio     = float('NaN')
+                self.tapeAlloc = float('NaN')
 		if not len(args):
 			self.setdefaultparameters()
@@ -43,4 +44,5 @@
 		s+="%s\n" % fielddisplay(self,'gcTriggerRatio',"free location block sorting/consolidation triggered if the ratio between allocated and used locations exceeds gcTriggerRatio")
 		s+="%s\n" % fielddisplay(self,'gcTriggerMaxSize',"free location block sorting/consolidation triggered if the allocated locations exceed gcTriggerMaxSize)")
+                s+="%s\n" % fielddisplay(self,'tapeAlloc','Iteration count of a priori memory allocation of the AD tape');
 
 		return s
@@ -54,4 +56,5 @@
 		self.gcTriggerRatio=2.0
 		self.gcTriggerMaxSize=65536
+                self.tapeAlloc    = 15000000;
 		return self
 	# }}}
@@ -68,4 +71,5 @@
 		md = checkfield(md,'fieldname','autodiff.gcTriggerRatio','>=',2.0)
 		md = checkfield(md,'fieldname','autodiff.gcTriggerMaxSize','>=',65536)
+                md = checkfield(md,'fieldname','autodiff.tapeAlloc','>=',0);
 
 		#Driver value:
@@ -97,5 +101,6 @@
 		WriteData(fid,prefix,'object',self,'fieldname','gcTriggerRatio','format','Double');
 		WriteData(fid,prefix,'object',self,'fieldname','gcTriggerMaxSize','format','Double');
-		#}}}
+                WriteData(fid,prefix,'object',self,'fieldname','tapeAlloc','format','Integer');
+                #}}}
 		#process dependent variables {{{
 		num_dependent_objects=len(self.dependents)
Index: issm/trunk/src/m/classes/cfdragcoeffabsgrad.m
===================================================================
--- issm/trunk/src/m/classes/cfdragcoeffabsgrad.m	(revision 23394)
+++ issm/trunk/src/m/classes/cfdragcoeffabsgrad.m	(revision 23394)
@@ -0,0 +1,78 @@
+%CFDRAGCOEFFABSGRAD class definition
+%
+%   Usage:
+%      cfdragcoeffabsgrad=cfdragcoeffabsgrad();
+%      cfdragcoeffabsgrad=cfdragcoeffabsgrad('name','SurfaceAltimetry',...
+%                    'definitionstring','Outputdefinition1',... 
+%							'model_string','Surface',...
+%                    'weights',ones(md.mesh.numberofvertices,1),...
+%                    'weights_string','WeightsSurfaceObservations');
+%
+%
+
+classdef cfdragcoeffabsgrad
+	properties (SetAccess=public)
+		%cfdragcoeffabsgrad
+		name               = '';
+		definitionstring   = ''; %string that identifies this output definition uniquely, from 'Outputdefinition[1-100]'
+		weights            = NaN; %weight coefficients for every vertex
+		weights_string     = ''; %string to identify this particular set of weights
+		cumulated          = NaN; %do we cumulate cfdragcoeffabsgrad through time?
+	end
+	
+	methods
+		function self = extrude(self,md) % {{{
+			if ~isnan(self.weights)
+				self.weights=project3d(md,'vector',self.weights,'type','node');
+			end
+		end % }}}
+		function self = cfdragcoeffabsgrad(varargin) % {{{
+			if nargin==0,
+				self=setdefaultparameters(self);
+			else
+				%use provided options to change fields
+				options=pairoptions(varargin{:});
+
+				%get name
+				self.name=getfieldvalue(options,'name','');
+				self.definitionstring=getfieldvalue(options,'definitionstring');
+				self.weights=getfieldvalue(options,'weights',NaN);
+				self.weights_string=getfieldvalue(options,'weights_string','');
+
+			end
+		end % }}}
+		function self = setdefaultparameters(self) % {{{
+		end % }}}
+		function md = checkconsistency(self,md,solution,analyses) % {{{
+
+			if ~ischar(self.name),
+				error('cfdragcoeffabsgrad error message: ''name'' field should be a string!');
+			end
+			OutputdefinitionStringArray={};
+			for i=1:100
+				OutputdefinitionStringArray{i}=strcat('Outputdefinition',num2str(i));
+			end
+			md = checkfield(md,'fieldname','self.definitionstring','field',self.definitionstring,'values',OutputdefinitionStringArray);
+
+			md = checkfield(md,'fieldname','self.weights','field',self.weights,'timeseries',1,'NaN',1,'Inf',1);
+
+		end % }}}
+		function md = disp(self) % {{{
+		
+			disp(sprintf('   TimeMisfit:\n'));
+
+			fielddisplay(self,'name','identifier for this cfdragcoeffabsgrad response');
+			fielddisplay(self,'definitionstring','string that identifies this output definition uniquely, from ''Outputdefinition[1-10]''');
+			fielddisplay(self,'weights','weights (at vertices) to apply to the cfdragcoeffabsgrad');
+			fielddisplay(self,'weights_string','string for weights for identification purposes');
+
+		end % }}}
+		function md = marshall(self,prefix,md,fid) % {{{
+
+		WriteData(fid,prefix,'data',self.name,'name','md.cfdragcoeffabsgrad.name','format','String');
+		WriteData(fid,prefix,'data',self.definitionstring,'name','md.cfdragcoeffabsgrad.definitionstring','format','String');
+		WriteData(fid,prefix,'data',self.weights,'name','md.cfdragcoeffabsgrad.weights','format','DoubleMat','mattype',1,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts);
+		WriteData(fid,prefix,'data',self.weights_string,'name','md.cfdragcoeffabsgrad.weights_string','format','String');
+		end % }}}
+	end
+end
Index: issm/trunk/src/m/classes/clusters/stallo.m
===================================================================
--- issm/trunk/src/m/classes/clusters/stallo.m	(revision 23394)
+++ issm/trunk/src/m/classes/clusters/stallo.m	(revision 23394)
@@ -0,0 +1,218 @@
+%        Stallo cluster class definition
+%	        This is a SLURM queue
+%	        The priorities are given to:
+%	           - Large jobs
+%	           - Short jobs
+%	           - small number of job per user
+%
+%	        There are some 20cpu nodes and 16cpu nodes, with 32GB (a few with 128GB) mem per node, you can ask for part of a node if you need more memory.(1 node, 2 CPUS and 10GB per cpu for example)
+
+%   Usage:
+%      cluster=stallo();
+%      cluster=stallo('np',3);
+%      cluster=stallo('np',3,'login','username');
+
+%node task and cpu must be defined, ask andreas for his stallo.py?
+
+classdef stallo
+    properties (SetAccess=public)
+		 % {{{
+		 name           = 'stallo';
+		 login          = '';
+		 numnodes       = 2;
+		 cpuspernode    = 10;
+		 mem            = 1.5;
+		 queue          = 'normal';
+		 time           = 2*60;
+		 codepath       = '';
+		 executionpath  = '';
+		 interactive    = 0;
+		 port           = [];
+		 accountname    = '';
+		 profiling	= 0;
+		 bbftp          = 0;
+		 % }}}
+	 end
+	 methods
+		 function cluster=stallo(varargin) % {{{
+
+			 %initialize cluster using default settings if provided
+			 if (exist('stallo_settings')==2), stallo_settings; end
+
+			 %use provided options to change fields
+			 cluster=AssignObjectFields(pairoptions(varargin{:}),cluster);
+		 end
+		 %}}}
+		 function disp(cluster) % {{{
+			 %  display the object
+			 disp(sprintf('class ''%s'' object ''%s'' = ',class(cluster),inputname(1)));
+			 disp(sprintf('    name: %s',cluster.name));
+			 disp(sprintf('    login: %s',cluster.login));
+       disp(sprintf('    accountname: %s',cluster.accountname));
+			 disp(sprintf('    numnodes: %i',cluster.numnodes));
+			 disp(sprintf('    cpuspernode: %i, cpu per nodes',cluster.cpuspernode));
+			 disp(sprintf('    queue: %s, name of the queue (normal (D), short,singlenode,multinode,devel)',cluster.queue));
+			 disp(sprintf('    codepath: %s',cluster.codepath));
+			 disp(sprintf('    executionpath: %s',cluster.executionpath));
+			 disp(sprintf('    interactive: %i',cluster.interactive));
+			 disp(sprintf('    time: %i, walltime requested in minutes',cluster.time));
+			 disp(sprintf('    memory: %i, memory per CPU',cluster.mem));
+			 disp(sprintf('    profiling: %i, enable profiling if 1 default is 0',cluster.profiling));
+		 end
+		 %}}}
+		 function md = checkconsistency(cluster,md,solution,analyses) % {{{
+
+			 available_queues={'short','normal','singlenode','multinode','devel'};
+			 queue_requirements_time=[60 2*24*60 28*24*60 28*24*60 4*60];
+			 queue_requirements_np=[2048 2048 20 2048 2048];
+
+			 QueueRequirements(available_queues,queue_requirements_time,queue_requirements_np,cluster.queue,cluster.np,1)
+
+			 %Miscelaneous
+			 if isempty(cluster.login), md = checkmessage(md,'login empty'); end
+       if isempty(cluster.accountname), md = checkmessage(md,'accountname empty'); end
+			 if isempty(cluster.codepath), md = checkmessage(md,'codepath empty'); end
+			 if isempty(cluster.executionpath), md = checkmessage(md,'executionpath empty'); end
+
+		 end
+		 %}}}
+		 function numprocs=np(cluster) % {{{
+			 %compute number of processors
+			 numprocs=cluster.numnodes*cluster.cpuspernode;
+		 end
+		 %}}}
+		 function BuildQueueScript(cluster,dirname,modelname,solution,io_gather,isvalgrind,isgprof,isdakota,isoceancoupling) % {{{
+
+			 if(isvalgrind), disp('valgrind not supported by cluster, ignoring...'); end
+			 if(isgprof),    disp('gprof not supported by cluster, ignoring...'); end
+
+			 executable='issm.exe';
+			 if isdakota,
+				 version=IssmConfig('_DAKOTA_VERSION_'); version=str2num(version(1:3));
+				 if (version>=6),
+					 executable='issm_dakota.exe';
+				 end
+			 end
+			 if isoceancoupling,
+				 executable='issm_ocean.exe';
+			 end
+
+			 days=floor(cluster.time/(60*24));
+			 hours=floor((cluster.time-(days*60*24))/60);
+			 minutes=floor(mod((cluster.time-(days*60*24)-(hours*60)),60));
+
+			 %write queuing script
+			 fid=fopen([modelname '.queue'],'w');
+			 fprintf(fid,'#!/bin/bash -l\n');
+			 fprintf(fid,'#SBATCH --job-name=%s \n',modelname);
+			 fprintf(fid,'#SBATCH --qos=%s \n',cluster.queue);
+			 fprintf(fid,'#SBATCH --nodes=%i \n',cluster.numnodes);
+			 fprintf(fid,'#SBATCH --ntasks-per-node=%i \n',cluster.cpuspernode);
+			 fprintf(fid,'#SBATCH --time=%02i-%02i:%02i:00 \n',days,hours,minutes);
+			 fprintf(fid,'#SBATCH --mem-per-cpu=%iMB\n',1000*cluster.mem); % mem in MB
+			 if (mod(cluster.np,16)+mod(cluster.np,20))==0,
+			 	fprintf(fid,'#SBATCH --ntask=%i\n',cluster.np);
+			 end
+			 fprintf(fid,'#SBATCH --account=%s\n',cluster.accountname);
+ 			 fprintf(fid,'#SBATCH --output %s/%s/%s.outlog \n',cluster.executionpath,dirname,modelname);
+ 			 fprintf(fid,'#SBATCH --error %s/%s/%s.errlog \n\n',cluster.executionpath,dirname,modelname);
+
+ 			 fprintf(fid,'export ISSM_DIR="%s/../"\n',cluster.codepath);%FIXME
+ 			 fprintf(fid,'module purge\n');
+ 			 fprintf(fid,'module load CMake/3.8.0-GCCcore-6.3.0\n');
+ 			 fprintf(fid,'module load Automake/1.15.1-GCCcore-6.3.0\n');
+ 			 fprintf(fid,'module load libtool/2.4.6\n');
+ 			 fprintf(fid,'module load OpenSSL/1.1.0e-intel-2017a\n');
+ 			 fprintf(fid,'module load PETSc/3.7.5-intel-2017a-downloaded-deps\n');
+
+ 			 fprintf(fid,'cd %s/%s/\n\n',cluster.executionpath,dirname);
+			 if cluster.profiling==1,
+			 	fprintf(fid,'module load perf-report\n');
+			 	fprintf(fid,'perf-report mpirun -np %i %s/%s %s %s/%s %s\n',cluster.np,cluster.codepath,executable,solution,cluster.executionpath,dirname,modelname);
+			 else
+			 	fprintf(fid,'mpirun -np %i %s/%s %s %s/%s %s\n',cluster.np,cluster.codepath,executable,solution,cluster.executionpath,dirname,modelname);
+			 end
+			 %}}}
+			 if ~io_gather, %concatenate the output files:
+				 fprintf(fid,'cat %s.outbin.* > %s.outbin',modelname,modelname);
+			 end
+			 fclose(fid);
+
+			 %in interactive mode, create a run file, and errlog and outlog file
+			 if cluster.interactive,
+			 	 fid=fopen([modelname '.run'],'w');
+			 	 fprintf(fid,'mpiexec -np %i %s/issm.exe %s %s %s\n',cluster.np,cluster.codepath,solution,[cluster.executionpath '/' dirname],modelname);
+		 	 	 if ~io_gather, %concatenate the output files:
+			 		 fprintf(fid,'cat %s.outbin.* > %s.outbin',modelname,modelname);
+			 	 end
+			 	 fclose(fid);
+			 	 fid=fopen([modelname '.errlog'],'w');
+			 	 fclose(fid);
+			 	 fid=fopen([modelname '.outlog'],'w');
+			 	 fclose(fid);
+			 end
+		 end
+
+
+		 function UploadQueueJob(cluster,modelname,dirname,filelist)% {{{
+
+			 %compress the files into one zip.
+			 compressstring=['tar -zcf ' dirname '.tar.gz '];
+			 for i=1:numel(filelist),
+				 compressstring = [compressstring ' ' filelist{i}];
+			 end
+			 if cluster.interactive,
+				 compressstring = [compressstring ' ' modelname '.run '  modelname '.errlog ' modelname '.outlog '];
+			 end
+			 system(compressstring);
+			 disp('uploading input file and queueing script');
+			 if cluster.interactive==10,
+				 directory=[pwd() '/run/'];
+			 elseif cluster.interactive,
+				 directory=[cluster.executionpath '/Interactive' num2str(cluster.interactive)];
+			 else
+				 directory=cluster.executionpath;
+			 end
+
+			 if ~cluster.bbftp,
+				 issmscpout(cluster.name,directory,cluster.login,cluster.port,{[dirname '.tar.gz']});
+			 else
+				 issmbbftpout(cluster.name,directory,cluster.login,cluster.port,cluster.numstreams,{[dirname '.tar.gz']});
+
+			 end
+		 end %}}}
+		 function LaunchQueueJob(cluster,modelname,dirname,filelist,restart,batch)% {{{
+
+			 %lauch command, to be executed via ssh
+			 if ~cluster.interactive,
+				 if ~isempty(restart)
+					 launchcommand=['cd ' cluster.executionpath ' && cd ' dirname ' && qsub ' modelname '.queue '];
+				 else
+					 launchcommand=['cd ' cluster.executionpath ' && rm -rf ./' dirname ' && mkdir ' dirname ...
+						 ' && cd ' dirname ' && mv ../' dirname '.tar.gz ./ && tar -zxf ' dirname '.tar.gz  && qsub ' modelname '.queue '];
+				 end
+			 else
+				 if ~isempty(restart)
+					 launchcommand=['cd ' cluster.executionpath '/Interactive' num2str(cluster.interactive)];
+				 else
+					 if cluster.interactive==10,
+						 launchcommand=['cd ' pwd() '/run && tar -zxf ' dirname '.tar.gz'];
+					 else
+						 launchcommand=['cd ' cluster.executionpath '/Interactive' num2str(cluster.interactive) ' && tar -zxf ' dirname '.tar.gz'];
+					 end
+				 end
+			 end
+
+			 disp('launching solution sequence on remote cluster');
+			 issmssh(cluster.name,cluster.login,cluster.port,launchcommand);
+		 end
+		 %}}}
+		 function Download(cluster,dirname,filelist)% {{{
+
+			 %copy files from cluster to current directory
+			 directory=[cluster.executionpath '/' dirname '/'];
+			 issmscpin(cluster.name,cluster.login,cluster.port,directory,filelist);
+
+		 end %}}}
+	end
+end
Index: issm/trunk/src/m/classes/clusters/stallo.py
===================================================================
--- issm/trunk/src/m/classes/clusters/stallo.py	(revision 23389)
+++ issm/trunk/src/m/classes/clusters/stallo.py	(revision 23394)
@@ -12,10 +12,10 @@
 except ImportError:
 	print 'You need stallo_settings.py to proceed, check presence and sys.path'
-	
+
 class stallo(object):
 	"""
 	Stallo cluster class definition
 	This is a SLURM queue
-	The priorities are given to: 
+	The priorities are given to:
 	   - Large jobs
 	   - Short jobs
@@ -23,5 +23,5 @@
 
 	There are some 20cpu nodes and 16cpu nodes, with 32GB (a few with 128GB) mem per node, you can ask for part of a node if you need more memory.(1 node, 2 CPUS and 10GB per cpu for example)
-	
+
 
 	   Usage:
@@ -51,7 +51,7 @@
 		#OK get other fields
 		self=options.AssignObjectFields(self)
-		self.np=self.numnodes*self.cpuspernode		
+		self.np=self.numnodes*self.cpuspernode
 	# }}}
-	
+
 	def __repr__(self):
 	# {{{
@@ -61,5 +61,5 @@
 		s = "%s\n%s"%(s,fielddisplay(self,'login','login'))
 		s = "%s\n%s"%(s,fielddisplay(self,'numnodes','number of nodes'))
-		s = "%s\n%s"%(s,fielddisplay(self,'cpuspernode','number of nodes per CPUs'))
+		s = "%s\n%s"%(s,fielddisplay(self,'cpuspernode','number of CPUs per nodes'))
 		s = "%s\n%s"%(s,fielddisplay(self,'mem','memory per CPU'))
 		s = "%s\n%s"%(s,fielddisplay(self,'queue','name of the queue (normal (D), short,singlenode,multinode,devel)'))
@@ -104,18 +104,23 @@
 		if isoceancoupling:
 			executable='issm_ocean.exe'
-		#write queuing script 
+		#write queuing script
 		shortname=modelname[0:min(12,len(modelname))]
+		timeobj=datetime.timedelta(minutes=self.time)
+		m,s=divmod(timeobj.total_seconds(), 60)
+		h,m=divmod(m, 60)
+		d,h=divmod(h, 60)
+		timestring="%02d-%02d:%02d:%02d" % (d, h, m, s)
+
 		fid=open(modelname+'.queue','w')
-									
 		fid.write('#!/bin/bash -l\n')
 		fid.write('#SBATCH --job-name=%s \n' % shortname)
-		fid.write('#SBATCH --partition %s \n' % self.queue)
-		fid.write('#SBATCH --nodes=%i' % self.numnodes)
-		fid.write('#SBATCH --ntasks-per-nodes==%i \n' % self.cpuspernode)									
-		fid.write('#SBATCH --time=%s\n' % self.time) #walltime is minutes
-		fid.write('#SBATCH --mem-per-cpu=%iGB\n' % self.mem)# mem is in GB
+		fid.write('#SBATCH --qos=%s \n' % self.queue)
+		fid.write('#SBATCH --nodes=%i \n' % self.numnodes)
+		fid.write('#SBATCH --ntasks-per-node=%i \n' % self.cpuspernode)
+		fid.write('#SBATCH --time={}\n'.format(timestring)) #walltime is minutes
+		fid.write('#SBATCH --mem-per-cpu={}MB\n'.format(int(1000*self.mem)))# mem is in MB
 		if (np.mod(self.np,16)+np.mod(self.np,20))==0:
 			fid.write('#SBATCH --ntask=%i\n' % self.np)
-		fid.write('#SBATCH --account=%s\n' % self.accountname) 
+		fid.write('#SBATCH --account=%s\n' % self.accountname)
 		fid.write('#SBATCH --output %s/%s/%s.outlog \n' % (self.executionpath,dirname,modelname))
 		fid.write('#SBATCH --error %s/%s/%s.errlog \n\n' % (self.executionpath,dirname,modelname))
Index: issm/trunk/src/m/classes/clusters/tetralith.m
===================================================================
--- issm/trunk/src/m/classes/clusters/tetralith.m	(revision 23394)
+++ issm/trunk/src/m/classes/clusters/tetralith.m	(revision 23394)
@@ -0,0 +1,216 @@
+%teralith class definition
+%
+%   Usage:
+%      cluster=tetralith();
+%      cluster=tetralith('np',3);
+%      cluster=tetralith('np',3,'login','username');
+
+classdef tetralith
+	properties (SetAccess=public)  
+		% {{{
+		name           = 'tetralith';
+		login          = '';
+		numnodes       = 2;
+		cpuspernode    = 32;
+		mem            = 2000; %MB
+		queue          = 'normal';
+		time           = 2*60; %[minutes]
+		codepath       = '';
+		executionpath  = '';
+		interactive    = 0;
+		port           = [];
+		accountname    = '';
+		% }}}
+	end
+	methods
+		function cluster=tetralith(varargin) % {{{
+
+			%initialize cluster using default settings if provided
+			if (exist('tetralith_settings')==2), tetralith_settings; end
+
+			%use provided options to change fields
+			cluster=AssignObjectFields(pairoptions(varargin{:}),cluster);
+		end
+		%}}}
+		function disp(cluster) % {{{
+			%  display the object
+			disp(sprintf('class ''%s'' object ''%s'' = ',class(cluster),inputname(1)));
+			disp(sprintf('    name: %s',cluster.name));
+			disp(sprintf('    login: %s',cluster.login));
+			disp(sprintf('    accountname: %s',cluster.accountname));
+			disp(sprintf('    numnodes: %i',cluster.numnodes));
+			disp(sprintf('    cpuspernode: %i',cluster.cpuspernode));
+			disp(sprintf('    np: %i', cluster.cpuspernode*cluster.numnodes));
+			disp(sprintf('    queue: %s',cluster.queue));
+			disp(sprintf('    codepath: %s',cluster.codepath));
+			disp(sprintf('    executionpath: %s',cluster.executionpath));
+			disp(sprintf('    interactive: %i',cluster.interactive));
+			disp(sprintf('    time: %i',cluster.time));
+			disp(sprintf('    memory: %i',cluster.mem));
+		end
+		%}}}
+		function md = checkconsistency(cluster,md,solution,analyses) % {{{
+
+			available_queues={'normal','devel'};
+			queue_requirements_time=[7*24*60 60]; 
+			queue_requirements_np=[1024 2*32];
+
+			QueueRequirements(available_queues,queue_requirements_time,queue_requirements_np,cluster.queue,cluster.np,1)
+
+			%Miscelaneous
+			if isempty(cluster.login), md = checkmessage(md,'login empty'); end
+			if isempty(cluster.accountname), md = checkmessage(md,'accountname empty'); end
+			if isempty(cluster.codepath), md = checkmessage(md,'codepath empty'); end
+			if isempty(cluster.executionpath), md = checkmessage(md,'executionpath empty'); end
+
+		end
+		%}}}
+		function numprocs=np(self) % {{{
+			%compute number of processors
+			numprocs=self.numnodes*self.cpuspernode;
+		end
+		%}}}
+		function BuildKrigingQueueScript(cluster,modelname,solution,io_gather,isvalgrind,isgprof) % {{{
+
+			if(isvalgrind), disp('valgrind not supported by cluster, ignoring...'); end
+			if(isgprof),    disp('gprof not supported by cluster, ignoring...'); end
+
+			%compute number of processors
+% 			cluster.np=cluster.numnodes*cluster.cpuspernode;
+			np(cluster);%=cluster.numnodes*cluster.cpuspernode;
+
+			%write queuing script 
+			fid=fopen([modelname '.queue'],'w');
+			fprintf(fid,'#!/bin/bash\n');
+			fprintf(fid,'#\n');
+			fprintf(fid,'#SBATCH --job-name=%s\n',modelname);
+% 			fprintf(fid,'#SBATCH -p %s \n',cluster.partition);
+			fprintf(fid,'#SBATCH -A %s \n',cluster.accountname);
+% 			fprintf(fid,'#SBATCH --mail-type=ALL\n');
+			fprintf(fid,'#SBATCH -N %i -n %i\n',cluster.numnodes,cluster.cpuspernode);
+			%calculate walltime in hh:mm:ss format
+			walltime=datestr(cluster.time/(60*24),'HH:MM:SS')
+			fprintf(fid,'#SBATCH -t %s\n',walltime); %walltime should be in hh:mm:ss
+			fprintf(fid,'#SBATCH --mem=%i\n',cluster.mem);
+			fprintf(fid,'#SBATCH -o %s.outlog \n',modelname);
+			fprintf(fid,'#SBATCH -e %s.errlog \n\n',modelname);
+% 			fprintf(fid,'module load intelcomp/17.0.0\n') %module load not recommended within job script at Tetralith
+% 			fprintf(fid,'module load mpt/2.14\n')
+% 			fprintf(fid,'module load petsc/3.7.4d\n')
+% 			fprintf(fid,'module load parmetis/4.0.3\n') 
+% 			fprintf(fid,'module load mumps/5.0.2\n')
+% 			fprintf(fid,'export ISSM_DIR="%s"\n',cluster.codepath); %FIXME
+			fprintf(fid,'export ISSM_DIR="%s/../"\n',cluster.codepath); %FIXME
+			fprintf(fid,'source $ISSM_DIR/etc/environment.sh\n');       %FIXME
+			fprintf(fid,'cd %s/%s\n\n',cluster.executionpath,dirname);
+% 			fprintf(fid,'mpiexec -np %i %s/%s %s %s %s\n',cluster.np,cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname);
+% 			fprintf(fid,'mpiexec_mpt -np %i %s/%s %s %s %s\n',cluster.np,cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname);
+			 fprintf(fid,'mpiexec -np %i %s/issm.exe %s %s %s\n',cluster.np,cluster.codepath,solution,[cluster.executionpath '/' dirname],modelname);
+% 			fprintf(fid,'mpirun -np %i %s/issm.exe %s %s %s\n',cluster.np,cluster.codepath,solution,[cluster.executionpath '/' dirname],modelname);
+			 if ~io_gather, %concatenate the output files:
+				 fprintf(fid,'cat %s.outbin.* > %s.outbin',modelname,modelname);
+			 end
+			 fclose(fid);
+		end
+		%}}}
+		function BuildQueueScript(cluster,dirname,modelname,solution,io_gather,isvalgrind,isgprof,isdakota,isoceancoupling) % {{{
+
+			if(isvalgrind), disp('valgrind not supported by cluster, ignoring...'); end
+			if(isgprof),    disp('gprof not supported by cluster, ignoring...'); end
+
+			executable='issm.exe';
+			if isdakota,
+				version=IssmConfig('_DAKOTA_VERSION_'); version=str2num(version(1:3));
+				if (version>=6),
+					executable='issm_dakota.exe';
+				end
+			end
+			if isoceancoupling,
+				executable='issm_ocean.exe';
+			end
+
+			%compute number of processors
+% 			cluster.np=cluster.numnodes*cluster.cpuspernode;
+			np(cluster);%=cluster.numnodes*cluster.cpuspernode;                     
+% 			shortname = substring(modelname,1,min(12,length(modelname)));
+
+			%write queuing script 
+			fid=fopen([modelname '.queue'],'w');
+			fprintf(fid,'#!/bin/bash\n');
+			fprintf(fid,'#\n');
+			fprintf(fid,'#SBATCH --job-name=%s\n',modelname);
+% 			fprintf(fid,'#SBATCH -p %s \n',cluster.partition);
+			fprintf(fid,'#SBATCH -A %s \n',cluster.accountname);
+% 			fprintf(fid,'#SBATCH --mail-type=ALL\n');
+			fprintf(fid,'#SBATCH -N %i -n %i\n',cluster.numnodes,cluster.cpuspernode);
+			%calculate walltime in hh:mm:ss format
+			walltime=datestr(cluster.time/(60*24),'HH:MM:SS');
+			fprintf(fid,'#SBATCH -t %s\n',walltime); %walltime should be in hh:mm:ss
+			fprintf(fid,'#SBATCH --mem=%i\n',cluster.mem);
+			fprintf(fid,'#SBATCH -o %s.outlog \n',modelname);
+			fprintf(fid,'#SBATCH -e %s.errlog \n\n',modelname);
+% 			fprintf(fid,'module load intelcomp/17.0.0\n') %module load not recommended within job script at Tetralith
+% 			fprintf(fid,'module load mpt/2.14\n')
+% 			fprintf(fid,'module load petsc/3.7.4d\n')
+% 			fprintf(fid,'module load parmetis/4.0.3\n') 
+% 			fprintf(fid,'module load mumps/5.0.2\n')
+			fprintf(fid,'export ISSM_DIR="%s/../"\n',cluster.codepath); %FIXME
+% 			fprintf(fid,'export ISSM_DIR="%s"\n',cluster.codepath); %FIXME
+			fprintf(fid,'source $ISSM_DIR/etc/environment.sh\n');       %FIXME
+			fprintf(fid,'cd %s/%s\n\n',cluster.executionpath,dirname);
+% 			fprintf(fid,'mpiexec -np %i %s/%s %s %s %s\n',cluster.np,cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname);
+			 fprintf(fid,'mpiexec -np %i %s/issm.exe %s %s %s\n',cluster.np,cluster.codepath,solution,[cluster.executionpath '/' dirname],modelname);
+% 			fprintf(fid,'mpirun -np %i %s/issm.exe %s %s %s\n',cluster.np,cluster.codepath,solution,[cluster.executionpath '/' dirname],modelname);
+% 			fprintf(fid,'mpiexec_mpt -np %i %s/%s %s %s %s\n',cluster.np,cluster.codepath,executable,solution,[cluster.executionpath '/' dirname],modelname);
+
+			if ~io_gather, %concatenate the output files:
+				fprintf(fid,'cat %s.outbin.* > %s.outbin',modelname,modelname);
+			end
+			fclose(fid);
+
+			%in interactive mode, create a run file, and errlog and outlog file
+			if cluster.interactive,
+				fid=fopen([modelname '.run'],'w');
+				fprintf(fid,'mpiexec_mpt -np %i %s/issm.exe %s %s %s\n',cluster.np,cluster.codepath,solution,[cluster.executionpath '/' dirname],modelname);
+				if ~io_gather, %concatenate the output files:
+					fprintf(fid,'cat %s.outbin.* > %s.outbin',modelname,modelname);
+				end
+				fclose(fid);
+				fid=fopen([modelname '.errlog'],'w');
+				fclose(fid);
+				fid=fopen([modelname '.outlog'],'w');
+				fclose(fid);
+			end
+		end %}}}
+		function UploadQueueJob(cluster,modelname,dirname,filelist)% {{{
+
+			%compress the files into one zip.
+			compressstring=['tar -zcf ' dirname '.tar.gz '];
+			for i=1:numel(filelist),
+				compressstring = [compressstring ' ' filelist{i}];
+			end
+			system(compressstring);
+			disp('uploading input file and queueing script');
+			directory=cluster.executionpath;
+% 			issmbbftpout(cluster.name,directory,cluster.login,cluster.port,cluster.numstreams,{[dirname '.tar.gz']});
+			issmscpout(cluster.name,directory,cluster.login,cluster.port,{[dirname '.tar.gz']});
+
+		end
+		%}}}
+		function LaunchQueueJob(cluster,modelname,dirname,filelist,restart,batch)% {{{
+
+			disp('launching solution sequence on remote cluster');
+			launchcommand=['cd ' cluster.executionpath ' && rm -rf ./' dirname ' && mkdir ' dirname ...
+				' && cd ' dirname ' && mv ../' dirname '.tar.gz ./ && tar -zxf ' dirname '.tar.gz  && hostname && sbatch ' modelname '.queue '];
+
+			issmssh(cluster.name,cluster.login,cluster.port,launchcommand);
+		end %}}}
+		function Download(cluster,dirname,filelist)% {{{
+
+			%copy files from cluster to current directory
+			directory=[cluster.executionpath '/' dirname '/'];
+			issmscpin(cluster.name,cluster.login,cluster.port,directory,filelist);
+
+		end %}}}
+	end
+end
Index: issm/trunk/src/m/classes/geometry.py
===================================================================
--- issm/trunk/src/m/classes/geometry.py	(revision 23389)
+++ issm/trunk/src/m/classes/geometry.py	(revision 23394)
@@ -13,9 +13,9 @@
 
 	def __init__(self): # {{{
-		self.surface           = float('NaN')
-		self.thickness         = float('NaN')
+		self.surface		= float('NaN')
+		self.thickness		= float('NaN')
 		self.base               = float('NaN')
-		self.bed        = float('NaN')
-		self.hydrostatic_ratio = float('NaN')
+		self.bed		= float('NaN')
+		self.hydrostatic_ratio	= float('NaN')
 
 		#set defaults
Index: issm/trunk/src/m/classes/groundingline.js
===================================================================
--- issm/trunk/src/m/classes/groundingline.js	(revision 23389)
+++ issm/trunk/src/m/classes/groundingline.js	(revision 23394)
@@ -29,5 +29,5 @@
 			checkfield(md,'fieldname','groundingline.melt_interpolation','values',['NoMeltOnPartiallyFloating', 'SubelementMelt1', 'SubelementMelt2', 'FullMeltOnPartiallyFloating']);
 
-			if (this.migration !='None'){
+			if(this.migration !='None' & md.trans.isgroundingline==1 & solution == 'TransientSolution'){
 				if (isNaN(md.geometry.bed)){
 					md.checkmessage('requesting grounding line migration, but bathymetry is absent!');
Index: issm/trunk/src/m/classes/groundingline.m
===================================================================
--- issm/trunk/src/m/classes/groundingline.m	(revision 23389)
+++ issm/trunk/src/m/classes/groundingline.m	(revision 23394)
@@ -33,5 +33,5 @@
 			md = checkfield(md,'fieldname','groundingline.melt_interpolation','values',{'NoMeltOnPartiallyFloating' 'SubelementMelt1' 'SubelementMelt2' 'FullMeltOnPartiallyFloating'});
 
-			if ~strcmp(self.migration,'None'),
+			if ~strcmp(self.migration,'None') & strcmp(solution,'TransientSolution') & md.transient.isgroundingline==1,
 				if isnan(md.geometry.bed),
 					md = checkmessage(md,['requesting grounding line migration, but bathymetry is absent!']);
Index: issm/trunk/src/m/classes/groundingline.py
===================================================================
--- issm/trunk/src/m/classes/groundingline.py	(revision 23389)
+++ issm/trunk/src/m/classes/groundingline.py	(revision 23394)
@@ -45,5 +45,5 @@
 		md = checkfield(md,'fieldname','groundingline.melt_interpolation','values',['SubelementMelt1','SubelementMelt2','NoMeltOnPartiallyFloating','FullMeltOnPartiallyFloating'])
 
-		if not m.strcmp(self.migration,'None'):
+		if(not m.strcmp(self.migration,'None') and md.transient.isgroundingline and solution=='TransientSolution'):
 			if np.any(np.isnan(md.geometry.bed)):
 				md.checkmessage("requesting grounding line migration, but bathymetry is absent!")
Index: issm/trunk/src/m/classes/numberedcostfunction.m
===================================================================
--- issm/trunk/src/m/classes/numberedcostfunction.m	(revision 23389)
+++ issm/trunk/src/m/classes/numberedcostfunction.m	(revision 23394)
@@ -1,3 +1,3 @@
-%M1QN3INVERSION class definition
+%NUMBEREDCOSTFUNCTION class definition
 %
 %   Usage:
@@ -44,18 +44,18 @@
 		function md = checkconsistency(self,md,solution,analyses) % {{{
 
-			num_costfunc=size(md.inversion.cost_functions,2);
+			num_costfunc=size(self.cost_functions,2);
 
-			md = checkfield(md,'fieldname','inversion.cost_functions','size',[1 num_costfunc],'values',supportedcostfunctions());
-			md = checkfield(md,'fieldname','inversion.cost_functions_coefficients','size',[md.mesh.numberofvertices num_costfunc],'>=',0);
-
+			md = checkfield(md,'fieldname','md.outputdefinition.definition{X}.dependent{X}.cost_functions','field',self.cost_functions,'size',[1 num_costfunc],'values',supportedcostfunctions());
+			md = checkfield(md,'fieldname','md.outputdefinition.definition{X}.cost_functions_coefficients','field',self.cost_functions_coefficients,'size',[md.mesh.numberofvertices numel(self.cost_functions)],'>=',0);
+			
 			if strcmp(solution,'BalancethicknessSolution')
-				md = checkfield(md,'fieldname','inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1,'Inf',1);
-				md = checkfield(md,'fieldname','inversion.surface_obs','size',[md.mesh.numberofvertices 1],'NaN',1,'Inf',1);
+				md = checkfield(md,'fieldname','md.outputdefinition.definition{X}.thickness_obs','field',self.thickness_obs,'size',[md.mesh.numberofvertices 1],'NaN',1,'Inf',1);
+				md = checkfield(md,'fieldname','md.outputdefinition.definition{X}.surface_obs','field',self.surface_obs,'size',[md.mesh.numberofvertices 1],'NaN',1,'Inf',1);
 			elseif strcmp(solution,'BalancethicknessSoftSolution')
-				md = checkfield(md,'fieldname','inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1,'Inf',1);
+				md = checkfield(md,'fieldname','md.outputdefinition.definition{X}.thickness_obs','field',self.thickness_obs,'size',[md.mesh.numberofvertices 1],'NaN',1,'Inf',1);
 			else
-				md = checkfield(md,'fieldname','inversion.vx_obs','size',[md.mesh.numberofvertices 1],'NaN',1,'Inf',1);
+				md = checkfield(md,'fieldname','md.outputdefinition.definition{X}.vx_obs','field',self.vx_obs,'size',[md.mesh.numberofvertices 1],'NaN',1,'Inf',1);
 				if ~strcmp(domaintype(md.mesh),'2Dvertical'),
-					md = checkfield(md,'fieldname','inversion.vy_obs','size',[md.mesh.numberofvertices 1],'NaN',1,'Inf',1);
+					md = checkfield(md,'fieldname','md.outputdefinition.definition{X}.vy_obs','field',self.vy_obs,'size',[md.mesh.numberofvertices 1],'NaN',1,'Inf',1);
 				end
 			end
Index: issm/trunk/src/m/classes/taoinversion.py
===================================================================
--- issm/trunk/src/m/classes/taoinversion.py	(revision 23389)
+++ issm/trunk/src/m/classes/taoinversion.py	(revision 23394)
@@ -97,5 +97,5 @@
 		else:
 			self.algorithm = 'tao_blmvm';
-		
+
 		#several responses can be used:
 		self.cost_functions=101;
@@ -110,8 +110,8 @@
 		if numel(self.cost_functions_coefficients) > 1:
 			self.cost_functions_coefficients=project3d(md,'vector',self.cost_functions_coefficients,'type','node')
-		
+
 		if numel(self.min_parameters) > 1:
 			self.min_parameters=project3d(md,'vector',self.min_parameters,'type','node')
-		
+
 		if numel(self.max_parameters)>1:
 			self.max_parameters=project3d(md,'vector',self.max_parameters,'type','node')
@@ -123,5 +123,5 @@
 			return md
 		if not IssmConfig('_HAVE_TAO_')[0]:
-			md = checkmessage(md,['TAO has not been installed, ISSM needs to be reconfigured and recompiled with TAO'])
+			md = md.checkmessage('TAO has not been installed, ISSM needs to be reconfigured and recompiled with TAO')
 
 
Index: issm/trunk/src/m/contrib/defleurian/netCDF/export_netCDF.py
===================================================================
--- issm/trunk/src/m/contrib/defleurian/netCDF/export_netCDF.py	(revision 23389)
+++ issm/trunk/src/m/contrib/defleurian/netCDF/export_netCDF.py	(revision 23394)
@@ -18,5 +18,5 @@
 			print ('New file name is {}'.format(newname))
 			filename=newname
-			
+
 	NCData=Dataset(filename, 'w', format='NETCDF4')
 	NCData.description = 'Results for run' + md.miscellaneous.name
@@ -100,10 +100,10 @@
 				Subgroup.__setattr__('classtype',md.__dict__[group].__class__.__name__)
 				subfields=dict.keys(md.__dict__[group].__dict__[field].__dict__)
-                                
+
 				for subfield in subfields:
 					if str(subfield)!='outlog':
 						Var=md.__dict__[group].__dict__[field].__dict__[subfield]
 						DimDict=CreateVar(NCData,Var,subfield,Subgroup,DimDict)
-				
+
 	NCData.close()
 
@@ -130,9 +130,10 @@
 							str:str,
 							dict:str}
-		
+
 	val_dim=np.shape(val_shape)[0]
+
 	#Now define and fill up variable
 	#treating scalar string or bool as atribute
-	if val_type==str or val_type==unicode or val_type==bool:
+	if val_type in [str,unicode,bool]:
 		Group.__setattr__(str(field).swapcase(), str(var))
 	#treating list as string table
@@ -147,5 +148,5 @@
 		if val_shape==0:
 			ncvar= []
-		else:			
+		else:
 			for elt in range(0,val_shape[0]):
 				ncvar[elt] = var[elt]
@@ -164,5 +165,5 @@
 			ncvar[elt,1]=str(dict.values(var)[elt]) #converting to str to avoid potential problems
 	#Now dealing with numeric variables
-	else:
+	elif val_type in [float,'float64',np.float64,int,'int64']:
 		dimensions,DimDict=GetDim(NCData,var,val_shape,DimDict,val_dim)
 		ncvar = Group.createVariable(str(field),TypeDict[val_type],dimensions,zlib=True)
@@ -175,4 +176,6 @@
 		except TypeError: #type does not accept nan, get vallue of the variable
 			ncvar[:] = var
+	else:
+		print('WARNING type "{}" is unknown for "{}.{}"'.format(val_type,Group.name,field))
 	return DimDict
 
Index: issm/trunk/src/m/contrib/defleurian/paraview/enveloppeVTK.py
===================================================================
--- issm/trunk/src/m/contrib/defleurian/paraview/enveloppeVTK.py	(revision 23389)
+++ issm/trunk/src/m/contrib/defleurian/paraview/enveloppeVTK.py	(revision 23394)
@@ -9,11 +9,11 @@
 	creates a directory with the vtk files for displays in paraview
 	(only work for triangle and wedges based on their number of nodes)
-	
-	Give only the results for nw but could be extended to geometry, mask... 
-	
-	input: filename   destination 
+
+	Give only the results for nw but could be extended to geometry, mask...
+
+	input: filename   destination
 	(string)
 	------------------------------------------------------------------
-model      this is md 
+model      this is md
 	------------------------------------------------------------------
 	By default only the results are exported, you can add whichever
@@ -40,22 +40,38 @@
 		os.mkdir(filename)
 
-	IsEnveloppe=np.where(model.mesh.vertexonbase | model.mesh.vertexonsurface)
-	#get the element related variables
+	# {{{get the element related variables
 	if 'z' in dict.keys(model.mesh.__dict__):
-		points=np.column_stack((model.mesh.x,model.mesh.y,model.mesh.z))
-		num_of_elt=np.size(np.isnan(model.mesh.lowerelements))+np.size(np.isnan(model.mesh.upperelements))
-		low_elt_num=np.size(np.isnan(model.mesh.lowerelements))
-		top_elt_num=np.size(np.isnan(model.mesh.upperelements))
+		is_enveloppe=np.logical_or(model.mesh.vertexonbase,model.mesh.vertexonsurface)
+		enveloppe_index=np.where(is_enveloppe)[0]
+		convert_index=np.nan*np.ones(np.shape(model.mesh.x))
+		convert_index=np.asarray([[i,np.where(enveloppe_index==i)[0][0]] for i,val in enumerate(convert_index) if any(enveloppe_index==i)])
+		points=np.column_stack((model.mesh.x[enveloppe_index],
+														model.mesh.y[enveloppe_index],
+														model.mesh.z[enveloppe_index]))
+		low_elt_num=np.size(np.where(np.isnan(model.mesh.lowerelements)))
+		top_elt_num=np.size(np.where(np.isnan(model.mesh.upperelements)))
+		num_of_elt=low_elt_num+top_elt_num
+		connect=model.mesh.elements[np.where(is_enveloppe[model.mesh.elements-1])].reshape(int(num_of_elt),3)-1
+		for elt in range(0, num_of_elt):
+			connect[elt,0]=convert_index[np.where(convert_index==connect[elt,0])[0],1][0]
+			connect[elt,1]=convert_index[np.where(convert_index==connect[elt,1])[0],1][0]
+			connect[elt,2]=convert_index[np.where(convert_index==connect[elt,2])[0],1][0]
+
 	else:
-		points=np.column_stack((model.mesh.x,model.mesh.y,np.zeros(np.shape(model.mesh.x))))
+		points=np.column_stack((model.mesh.x,
+														model.mesh.y,
+														np.zeros(np.shape(model.mesh.x))))
 		num_of_elt=np.shape(model.mesh.elements)[0]
-		
-	num_of_points=np.size(points)[0]
-	dim=np.size(points)[1]
-	point_per_elt=np.shape(model.mesh.elements)[1]
-		
+		connect=model.mesh.elements-1
+		enveloppe_index=np.arange(0,np.size(model.mesh.x))
+
+	every_nodes=np.size(model.mesh.x)
+	num_of_points=np.size(enveloppe_index)
+	dim=3
+	point_per_elt=3
 	celltype=5 #triangles
-	
-	#this is the result structure
+
+	# }}}
+	# {{{this is the result structure
 	res_struct=model.results
 	if (len(res_struct.__dict__)>0):
@@ -64,13 +80,14 @@
 		num_of_sols=len(solnames)
 		num_of_timesteps=1
-		#%building solutionstructure 
+		#%building solutionstructure
 		for solution in solnames:
 			#looking for multiple time steps
 			if (np.size(res_struct.__dict__[solution])>num_of_timesteps):
 				num_of_timesteps=np.size(res_struct.__dict__[solution])
-				num_of_timesteps=int(num_of_timesteps)+1
+				num_of_timesteps=int(num_of_timesteps)
 	else:
 		num_of_timesteps=1
-
+	# }}}
+	# {{{write header and mesh
 	for step in range(0,num_of_timesteps):
 		timestep=step
@@ -83,17 +100,12 @@
 		for point in points:
 			fid.write('%f %f %f \n'%(point[0], point[1], point[2]))
-			
+
 		fid.write('CELLS %d %d\n' %(num_of_elt, num_of_elt*(point_per_elt+1)))
 
-		# 	if exist('low_elt_num')
-		# triaconnect=zeros(num_of_elt,3);
-		# triaconnect(1:low_elt_num,:)=model.mesh.elements(find(isnan(model.mesh.lowerelements)),1:3);
-		# upshift=-min(min(model.mesh.elements(find(isnan(model.mesh.upperelements)),4:6)))+1+max(max(model.mesh.elements(find(isnan(model.mesh.lowerelements)),1:3)));
-		# triaconnect(1+low_elt_num:num_of_elt,:)=model.mesh.elements(find(isnan(model.mesh.upperelements)),4:6)+upshift;
-		# fprintf(fid,s,[(3)*ones(num_of_elt,1) triaconnect-1]');
 		for elt in range(0, num_of_elt):
-		
-			fid.write('3 %d %d %d\n' %(model.mesh.elements[elt,0]-1,model.mesh.elements[elt,1]-1,model.mesh.elements[elt,2]-1))
-		
+			fid.write('3 %d %d %d\n' %(connect[elt,0],
+																 connect[elt,1],
+																 connect[elt,2]))
+
 		fid.write('CELL_TYPES %d\n' %num_of_elt)
 		for elt in range(0, num_of_elt):
@@ -101,6 +113,6 @@
 
 		fid.write('POINT_DATA %s \n' %str(num_of_points))
-	
-		#loop over the different solution structures
+		# }}}
+		# {{{loop over the different solution structures
 		if 'solnames' in locals():
 			for sol in solnames:
@@ -110,8 +122,8 @@
 				else:
 					timestep = np.size(res_struct.__dict__[sol])
-				
+
 				#getting the  fields in the solution
 				if(np.size(res_struct.__dict__[sol])>1):
-					fieldnames=dict.keys(res_struct.__dict__[sol].__getitem__(timestep-1).__dict__)
+					fieldnames=dict.keys(res_struct.__dict__[sol].__getitem__(timestep).__dict__)
 				else:
 					fieldnames=dict.keys(res_struct.__dict__[sol].__dict__)
@@ -119,39 +131,40 @@
 				for field in fieldnames:
 					if(np.size(res_struct.__dict__[sol])>1):
-						fieldstruct=res_struct.__dict__[sol].__getitem__(timestep-1).__dict__[field]
+						fieldstruct=res_struct.__dict__[sol].__getitem__(timestep).__dict__[field]
 					else:
 						fieldstruct=res_struct.__dict__[sol].__dict__[field]
 
-					if ((np.size(fieldstruct))==num_of_points):
+					if ((np.size(fieldstruct))==every_nodes):
 						fid.write('SCALARS %s float 1 \n' % field)
 						fid.write('LOOKUP_TABLE default\n')
 						for node in range(0,num_of_points):
 							#paraview does not like NaN, replacing
-							if np.isnan(fieldstruct[node]):
+							if np.isnan(fieldstruct[enveloppe_index[node]]):
 								fid.write('%e\n' % -9999.9999)
 							#also checking for verry small value that mess up
-							elif (abs(fieldstruct[node])<1.0e-20):
+							elif (abs(fieldstruct[enveloppe_index[node]])<1.0e-20):
 								fid.write('%e\n' % 0.0)
 							else:
-								fid.write('%e\n' % fieldstruct[node])
-					
-		#loop on arguments, if something other than result is asked, do
-		#it now
+								fid.write('%e\n' % fieldstruct[enveloppe_index[node]])
+		# }}}
+		# {{{loop on arguments, if something other than result is asked, do it now
+
 		for other in args:
 			other_struct=model.__dict__[other]
 			othernames=(dict.keys(other_struct.__dict__))
 			for field in othernames:
-#				fprintf(fid,s,res_struct.(fieldnames{k})(IsEnveloppe));
-				if ((np.size(other_struct.__dict__[field]))==num_of_points):
+				if ((np.size(other_struct.__dict__[field]))==every_nodes):
 					fid.write('SCALARS %s float 1 \n' % field)
 					fid.write('LOOKUP_TABLE default\n')
 					for node in range(0,num_of_points):
 						#paraview does not like NaN, replacing
-						if np.isnan(other_struct.__dict__[field][node]):
+						if np.isnan(other_struct.__dict__[field][enveloppe_index[node]]):
 							fid.write('%e\n' % -9999.9999)
 						#also checking for verry small value that mess up
-						elif (abs(other_struct.__dict__[field][node])<1.0e-20):
+						elif (abs(other_struct.__dict__[field][enveloppe_index[node]])<1.0e-20):
 							fid.write('%e\n' % 0.0)
 						else:
-							fid.write('%e\n' % other_struct.__dict__[field][node])
+							fid.write('%e\n' % other_struct.__dict__[field][enveloppe_index[node]])
+
+			# }}}
 	fid.close();
Index: issm/trunk/src/m/contrib/defleurian/paraview/exportVTK.py
===================================================================
--- issm/trunk/src/m/contrib/defleurian/paraview/exportVTK.py	(revision 23389)
+++ issm/trunk/src/m/contrib/defleurian/paraview/exportVTK.py	(revision 23394)
@@ -9,11 +9,11 @@
 	creates a directory with the vtk files for displays in paraview
 	(only work for triangle and wedges based on their number of nodes)
-	
-	Give only the results for nw but could be extended to geometry, mask... 
-	
-	input: filename   destination 
+
+	Give only the results for nw but could be extended to geometry, mask...
+
+	input: filename   destination
 	(string)
 	------------------------------------------------------------------
-model      this is md 
+model      this is md
 	------------------------------------------------------------------
 	By default only the results are exported, you can add whichever
@@ -67,5 +67,5 @@
 		num_of_sols=len(solnames)
 		num_of_timesteps=1
-		#%building solutionstructure 
+		#%building solutionstructure
 		for solution in solnames:
 			#looking for multiple time steps
@@ -91,7 +91,7 @@
 			for point in points:
 				fid.write('%f %f %f \n'%(point[0], point[1], point[2]))
-			
+
 		fid.write('CELLS %d %d\n' %(num_of_elt, num_of_elt*(point_per_elt+1)))
-		
+
 		if point_per_elt==3:
 			for elt in range(0, num_of_elt):
@@ -117,5 +117,5 @@
 				else:
 					timestep = np.size(res_struct.__dict__[sol])
-				
+
 				#getting the  fields in the solution
 				if(np.size(res_struct.__dict__[sol])>1):
@@ -187,11 +187,14 @@
 					# reloaded variable are generally of dim 2
 					elif np.shape(other_struct.__dict__[field])[0]==num_of_points:
+						# we want only vector
+						if np.shape(other_struct.__dict__[field])[1]==1:
 							fid.write('SCALARS %s float 1 \n' % field)
 							fid.write('LOOKUP_TABLE default\n')
 							for node in range(0,num_of_points):
 								#paraview does not like NaN, replacing
+								print other_struct.__dict__[field][node]
 								if np.isnan(other_struct.__dict__[field][node]):
 									fid.write('%e\n' % -9999.9999)
-								#also checking for verry small value that mess up
+									#also checking for verry small value that mess up
 								elif (abs(other_struct.__dict__[field][node])<1.0e-20):
 									fid.write('%e\n' % 0.0)
Index: issm/trunk/src/m/mesh/planet/gmsh/gmshplanet.m
===================================================================
--- issm/trunk/src/m/mesh/planet/gmsh/gmshplanet.m	(revision 23389)
+++ issm/trunk/src/m/mesh/planet/gmsh/gmshplanet.m	(revision 23394)
@@ -23,5 +23,5 @@
 	resolution=getfieldvalue(options,'resolution')*1000;
 
-	%initialize mesh: 
+	%initialize mesh:
 	mesh=mesh3dsurface;
 
@@ -97,5 +97,5 @@
 		end
 		fprintf(fid,'};\n');
-		
+
 		fclose(fid);
 		% }}}
@@ -111,5 +111,5 @@
 	end
 	if isempty(gmshpath),
-		error('gmt not found, make sure it is properly installed');
+		error('gmsh not found, make sure it is properly installed');
 	end
 
@@ -160,20 +160,20 @@
 	mesh.numberofelements=fscanf(fid,'%i',1);
 	A=fscanf(fid,'%i %i %i %i %i %i %i %i',[8 mesh.numberofelements]);
-	mesh.elements=A(6:8,:)'; 
+	mesh.elements=A(6:8,:)';
 	A=fscanf(fid,'%s',1);
 	if ~strcmp(A,'$EndElements'),
 		error(['Expecting $EndElements (' A ')']);
 	end
-	fclose(fid); 
+	fclose(fid);
 	%}}}
 
-	%figure out other fields in mesh3dsurface: 
+	%figure out other fields in mesh3dsurface:
 	mesh.r=sqrt(mesh.x.^2+mesh.y.^2+mesh.z.^2);
 	mesh.lat = asin(mesh.z./mesh.r)/pi*180;
 	mesh.long = atan2(mesh.y,mesh.x)/pi*180;
 
-	%erase files: 
+	%erase files:
 	system('rm -rf sphere.geo sphere.msh sphere.pos');
 
-	%return mesh: 
+	%return mesh:
 	return;
Index: issm/trunk/src/m/mesh/triangle.py
===================================================================
--- issm/trunk/src/m/mesh/triangle.py	(revision 23389)
+++ issm/trunk/src/m/mesh/triangle.py	(revision 23394)
@@ -2,7 +2,7 @@
 import numpy as np
 from mesh2d import mesh2d
-from Triangle import Triangle
 from NodeConnectivity import NodeConnectivity
 from ElementConnectivity import ElementConnectivity
+from Triangle_python import Triangle_python
 import MatlabFuncs as m
 
@@ -50,5 +50,5 @@
 	#Mesh using Triangle
 	md.mesh=mesh2d()
-	md.mesh.elements,md.mesh.x,md.mesh.y,md.mesh.segments,md.mesh.segmentmarkers=Triangle(domainname,riftname,area)
+	md.mesh.elements,md.mesh.x,md.mesh.y,md.mesh.segments,md.mesh.segmentmarkers=Triangle_python(domainname,riftname,area)
 	md.mesh.elements=md.mesh.elements.astype(int)
 	md.mesh.segments=md.mesh.segments.astype(int)
Index: issm/trunk/src/m/mesh/triangle2dvertical.m
===================================================================
--- issm/trunk/src/m/mesh/triangle2dvertical.m	(revision 23389)
+++ issm/trunk/src/m/mesh/triangle2dvertical.m	(revision 23394)
@@ -25,5 +25,5 @@
 
 %Mesh using Triangle
-[elements,x,z,segments,segmentmarkers]=Triangle(domainname,'',area);
+[elements,x,z,segments,segmentmarkers]=Triangle_matlab(domainname,'',area);
 
 %check that all the created nodes belong to at least one element
Index: issm/trunk/src/m/modules/Chaco.py
===================================================================
--- issm/trunk/src/m/modules/Chaco.py	(revision 23389)
+++ issm/trunk/src/m/modules/Chaco.py	(revision 23394)
@@ -5,5 +5,5 @@
 
    Usage:
-      [assgn] = Chaco(A,vwgts,ewgts,x,y,z,options,nparts,goal);
+      assgn = Chaco(A,vwgts,ewgts,x,y,z,options,nparts,goal);
 
    A:			Input adjacency matrix
Index: issm/trunk/src/m/modules/MeshPartition.m
===================================================================
--- issm/trunk/src/m/modules/MeshPartition.m	(revision 23389)
+++ issm/trunk/src/m/modules/MeshPartition.m	(revision 23394)
@@ -3,5 +3,5 @@
 %
 %	   Usage:
-%			[element_partitioning,node_partitioning]=MeshPartition(md,numpartitions)");
+%			[element_partitioning,node_partitioning]=MeshPartition(md,numpartitions);
 %
 %	   element_partitioning: Vector of partitioning area numbers, for every element.
@@ -35,3 +35,3 @@
 
 % Call mex module
-[element_partitioning, node_partitioning] = MeshPartition_matlab(numberofvertices,elements,numberofvertices2d,elements2d,numberoflayers,meshelementtype,numpartitions);
+[element_partitioning, node_partitioning] = MeshPartition_matlab(numberofvertices,elements,numberofvertices2d,elements2d,numberoflayers,elementtype,numpartitions);
Index: issm/trunk/src/m/modules/MeshPartition.py
===================================================================
--- issm/trunk/src/m/modules/MeshPartition.py	(revision 23389)
+++ issm/trunk/src/m/modules/MeshPartition.py	(revision 23394)
@@ -9,5 +9,5 @@
 
 	   Usage:
-			[element_partitioning,node_partitioning]=MeshPartition(md.mesh,numpartitions)")
+			[element_partitioning,node_partitioning]=MeshPartition(md.mesh,numpartitions)
 
 	   element_partitioning: Vector of partitioning area numbers, for every element.
@@ -38,5 +38,5 @@
 
 	#Call module
-	[element_partitioning, node_partitioning] = MeshPartition_python(numberofvertices, elements, numberofvertices2d, elements2d, numberoflayers, meshelementtype, numpartitions)
+	[element_partitioning, node_partitioning] = MeshPartition_python(numberofvertices, elements, numberofvertices2d, elements2d, numberoflayers,elementtype, numpartitions)
 
 	return [element_partitioning, node_partitioning]
Index: issm/trunk/src/m/modules/Scotch.py
===================================================================
--- issm/trunk/src/m/modules/Scotch.py	(revision 23389)
+++ issm/trunk/src/m/modules/Scotch.py	(revision 23394)
@@ -2,5 +2,5 @@
 
 def Scotch(*varargin):
-'''SCOTCH - Scotch partitioner
+	'''SCOTCH - Scotch partitioner
 
    Usage:
Index: issm/trunk/src/m/modules/Triangle.py
===================================================================
--- issm/trunk/src/m/modules/Triangle.py	(revision 23389)
+++ 	(revision )
@@ -1,21 +1,0 @@
-from Triangle_python import Triangle_python
-
-def Triangle(domainoutlinefilename,rifts,mesh_area):
-	"""
-	TRIMESH - Mesh a domain using an .exp file
-
-	   Usage: 
-			[index,x,y,segments,segmentmarkers]=Triangle(domainoutlinefilename,rifts,mesh_area); 
-
-	   index,x,y: defines a triangulation 
-		segments: An array made of exterior segments to the mesh domain outline 
-		segmentmarkers: An array flagging each segment
-
-	   domainoutlinefilename: an Argus domain outline file
-		mesh_area: The maximum area desired for any element of the resulting mesh
-	"""
-	# Call mex module
-	index,x,y,segments,segmentmarkers=Triangle_python(domainoutlinefilename,rifts,mesh_area)
-	# Return
-	return index,x,y,segments,segmentmarkers
-
Index: issm/trunk/src/m/partition/AreaAverageOntoPartition.py
===================================================================
--- issm/trunk/src/m/partition/AreaAverageOntoPartition.py	(revision 23394)
+++ issm/trunk/src/m/partition/AreaAverageOntoPartition.py	(revision 23394)
@@ -0,0 +1,59 @@
+import numpy as np
+
+def AreaAverageOntoPartition(md,vector,layer=None):
+	'''AREAAVERAGEONTOPARTITION 
+   compute partition values for a certain vector expressed on the vertices of the mesh.
+   Use area weighted average.
+
+   Usage:
+      average=AreaAverageOntoPartition(md,vector)
+      average=AreaAverageOntoPartition(md,vector,layer) #if in 3D, chose which layer is partitioned
+'''
+	#some checks
+	if len(np.shape(md.mesh)) == 3:
+		if layer == None:
+			raise RuntimeError('AreaAverageOntoPartition: layer should be provided onto which Area Averaging occurs')
+		
+		#save 3D model
+		md3d = md
+
+		md.mesh.elements = md.mesh.elements2d
+		md.mesh.x = md.mesh.x2d
+		md.mesh.y = md.mesh.y2d
+		md.mesh.numberofvertices = md.mesh.numberofvertices2d
+		md.mesh.numberofelements = md.mesh.numberofelements2d
+		md.qmu.vertex_weight = []
+		md.mesh.vertexconnectivity = []
+
+		#run connectivity routine
+		md = adjacency(md)
+
+		#finally, project vector: 
+		vector = project2d(md3d,vector,layer)
+		md.qmu.partition = project2d(md3d,md3d.qmu.partition,layer)
+
+
+	#ok, first check that part is Matlab indexed
+	#part = md.qmu.partition
+
+	#some check: 
+	if md.qmu.numberofpartitions != max(md.qmu.partition):
+		raise RuntimeError('AreaAverageOntoPartition error message: ''npart'' should be equal to max(md.qmu.partition)')
+
+
+	#initialize output
+	partvector = np.zeros((max(md.qmu.partition),))
+
+	#start weight average
+	weightedvector = vector*md.qmu.vertex_weight
+	for i in range(max(md.qmu.partition)):
+		pos=np.where(md.qmu.partition==i)
+		partvector[i]=sum(weightedvector[pos])/sum(md.qmu.vertex_weight[pos])
+
+
+	#in 3D, restore 3D model:
+	if len(np.shape(md.mesh)) == 3:
+		md = md3d
+
+	return partvector
+
Index: issm/trunk/src/m/partition/partitioner.py
===================================================================
--- issm/trunk/src/m/partition/partitioner.py	(revision 23389)
+++ issm/trunk/src/m/partition/partitioner.py	(revision 23394)
@@ -3,8 +3,9 @@
 import MatlabFuncs as m
 from adjacency import *
-#from Chaco import *
+from Chaco import *
 #from Scotch import *
-#from MeshPartition import *
+from MeshPartition import *
 from project3d import *
+from mesh2d import *
 
 def partitioner(md,*varargin):
@@ -60,27 +61,28 @@
 
 	if m.strcmpi(package,'chaco'):
-		raise RuntimeError('Chaco is not currently supported for this function')
+		#raise RuntimeError('Chaco is not currently supported for this function')
 
 		#  default method (from chaco.m)
-		#method=np.array([1,1,0,0,1,1,50,0,.001,7654321]).reshape(-1,1)
-		#method[0]=3    #  global method (3=inertial (geometric))
-		#method[2]=0    #  vertex weights (0=off, 1=on)
+		method=np.array([1,1,0,0,1,1,50,0,.001,7654321])
+		method[0]=3    #  global method (3=inertial (geometric))
+		method[2]=0    #  vertex weights (0=off, 1=on)
 
 		#specify bisection
-		#method[5]=options.getfieldvalue('section')#  ndims (1=bisection, 2=quadrisection, 3=octasection)
+		method[5]=options.getfieldvalue('section')#  ndims (1=bisection, 2=quadrisection, 3=octasection)
 
 		#are we using weights? 
-		#if m.strcmpi(options.getfieldvalue('weighting'),'on'):
-			#weights=np.floor(md.qmu.vertex_weight/min(md.qmu.vertex_weight))
-			#method[2]=1
-		#else:
-			#weights=[]
+		if m.strcmpi(options.getfieldvalue('weighting'),'on'):
+			weights=np.floor(md.qmu.vertex_weight/min(md.qmu.vertex_weight))
+			method[2]=1
+		else:
+			weights=[]
 	
+		method = method.reshape(-1,1)	# transpose to 1x10 instead of 10
+
 		#  partition into nparts
-		#if isinstance(md.mesh,mesh2d):
-			#part=Chaco(md.qmu.adjacency,weights,[],md.mesh.x, md.mesh.y,np.zeros((md.mesh.numberofvertices,)),method,npart,[]).T+1 #index partitions from 1 up. like metis.
-		#else:
-			#part=Chaco(md.qmu.adjacency,weights,[],md.mesh.x, md.mesh.y,md.mesh.z,method,npart,[]).T+1 #index partitions from 1 up. like metis.
-	
+		if isinstance(md.mesh,mesh2d):
+			part=np.array(Chaco(md.qmu.adjacency,weights,np.array([]),md.mesh.x, md.mesh.y,np.zeros((md.mesh.numberofvertices,)),method,npart,np.array([]))).T+1 #index partitions from 1 up. like metis.
+		else:
+			part=np.array(Chaco(md.qmu.adjacency,weights,np.array([]),md.mesh.x, md.mesh.y,md.mesh.z,method,npart,np.array([]))).T+1 #index partitions from 1 up. like metis.
 	
 	elif m.strcmpi(package,'scotch'):
Index: issm/trunk/src/m/plot/applyoptions.m
===================================================================
--- issm/trunk/src/m/plot/applyoptions.m	(revision 23389)
+++ issm/trunk/src/m/plot/applyoptions.m	(revision 23394)
@@ -142,4 +142,6 @@
 	if exist(options,'colorbarcornerposition'),
 		c=colorbar(getfieldvalue(options,'colorbarcornerposition'),'peer',gca);
+	elseif exist(options,'colorbarpos') & ischar(getfieldvalue(options,'colorbarpos')),
+		c=colorbar(getfieldvalue(options,'colorbarpos'));
 	else 
 		c=colorbar('peer',gca);
@@ -151,5 +153,5 @@
 		set(c,'Ylim',lim);
 	end
-	if exist(options,'colorbarpos'),
+	if exist(options,'colorbarpos') & isnumeric(getfieldvalue(options,'colorbarpos')),
 		set(c,'Position',getfieldvalue(options,'colorbarpos'));
 	end
Index: issm/trunk/src/m/plot/googlemaps.m
===================================================================
--- issm/trunk/src/m/plot/googlemaps.m	(revision 23389)
+++ issm/trunk/src/m/plot/googlemaps.m	(revision 23394)
@@ -123,5 +123,20 @@
 			'&scale=' num2str(scale)];
 		url = ['http://maps.google.com/maps/api/staticmap?' params];
-		[X, map]=imread(url,'png');
+		count = 0;
+		countmax = 10;
+		while(true)
+			try,
+				[X, map]=imread(url,'png');
+				break;
+			catch me,
+				count = count+1;
+				disp(['Failed, trying again... (' num2str(countmax-count) ' more attempts)']);
+				pause(.3);
+				if count>countmax,
+					disp('Giving up...');
+					rethrow(me);
+				end
+			end
+		end
 		X=ind2rgb(X,map);
 		indx1 = floor(x*width)+1;
Index: issm/trunk/src/m/qmu/dakota_in_write.py
===================================================================
--- issm/trunk/src/m/qmu/dakota_in_write.py	(revision 23389)
+++ issm/trunk/src/m/qmu/dakota_in_write.py	(revision 23394)
@@ -62,5 +62,5 @@
 	filei2=fullfile(pathstr,name+ext)
 
-	print 'Opening Dakota input file \''+filei2 + '\''
+	print 'Opening Dakota input file \''+filei2 + '\'.'
 	try:
 		with open(filei2,'w+') as fidi:
Index: issm/trunk/src/m/qmu/dakota_out_parse.py
===================================================================
--- issm/trunk/src/m/qmu/dakota_out_parse.py	(revision 23389)
+++ issm/trunk/src/m/qmu/dakota_out_parse.py	(revision 23394)
@@ -241,4 +241,15 @@
 	dmax95 =prctile_issm(data,95,0)
 
+	# Note: the following line may cause the following warning
+	#	(should not crash or invalidate results) when one of
+	#	the inputs does not change with respect to the
+	#	other/s causing an internal divide-by-zero error
+
+	#/usr/local/lib/python2.7/dist-packages/numpy/lib/function_base.py:3163:
+	#	RuntimeWarning: invalid value encountered in true_divide
+	#	c /= stddev[:,None]
+
+	#	(and/or the same but with "c /= stddev[None, :]")
+
 	dcorrel=np.corrcoef(data.T)
 
Index: issm/trunk/src/m/qmu/helpers.py
===================================================================
--- issm/trunk/src/m/qmu/helpers.py	(revision 23389)
+++ issm/trunk/src/m/qmu/helpers.py	(revision 23394)
@@ -250,5 +250,5 @@
 		pass
 
-	# if all of that fails, then if is not empty
+	# if all of that fails, then it is not empty
 	return False
 
Index: issm/trunk/src/m/qmu/preqmu.py
===================================================================
--- issm/trunk/src/m/qmu/preqmu.py	(revision 23389)
+++ issm/trunk/src/m/qmu/preqmu.py	(revision 23394)
@@ -45,6 +45,7 @@
 			raise RuntimeError('Existing '+str(options.qmudir)+' directory, cannot overwrite. Specify "overwrite","y" option in solve arguments.')
 	
-
-	os.makedirs(qmudir)
+	# os.makedirs() raises error when dir exists, matlab's mkdir() does not
+	if not os.path.isdir(qmudir):
+		os.makedirs(qmudir)
 	os.chdir(qmudir)
 
Index: issm/trunk/src/m/qmu/process_qmu_response_data.m
===================================================================
--- issm/trunk/src/m/qmu/process_qmu_response_data.m	(revision 23389)
+++ issm/trunk/src/m/qmu/process_qmu_response_data.m	(revision 23394)
@@ -43,8 +43,6 @@
 	%ok, process the domains named in qmu_mass_flux_profiles,  to build a list of segments (MatArray)
 	md.qmu.mass_flux_segments=cell(num_mass_flux,1);
-	md.qmu.mass_flux_segments
 	for i=1:num_mass_flux,
 		md.qmu.mass_flux_segments{i}=MeshProfileIntersection(md.mesh.elements,md.mesh.x,md.mesh.y,[md.qmu.mass_flux_profile_directory '/' md.qmu.mass_flux_profiles{i}]);
 	end
-	md.qmu.mass_flux_segments
 end
Index: issm/trunk/src/m/solve/WriteData.py
===================================================================
--- issm/trunk/src/m/solve/WriteData.py	(revision 23389)
+++ issm/trunk/src/m/solve/WriteData.py	(revision 23394)
@@ -7,5 +7,5 @@
 	"""
 	WRITEDATA - write model field in binary file
- 
+
 	   Usage:
 	      WriteData(fid,varargin)
@@ -57,5 +57,5 @@
 	#Step 1: write the enum to identify this record uniquely
 	fid.write(struct.pack('i',len(name)))
-	fid.write(struct.pack('%ds' % len(name),name)) 
+	fid.write(struct.pack('%ds' % len(name),name))
 
 	#Step 2: write the data itself.
@@ -67,6 +67,6 @@
 		fid.write(struct.pack('i',4+4))  #1 bool (disguised as an int)+code
 
-		#write data code: 
-		fid.write(struct.pack('i',FormatToCode(format))) 
+		#write data code:
+		fid.write(struct.pack('i',FormatToCode(format)))
 
 		#now write integer
@@ -81,9 +81,9 @@
 		fid.write(struct.pack('i',4+4))  #1 integer + code
 
-		#write data code: 
-		fid.write(struct.pack('i',FormatToCode(format))) 
+		#write data code:
+		fid.write(struct.pack('i',FormatToCode(format)))
 
 		#now write integer
-		fid.write(struct.pack('i',data)) 
+		fid.write(struct.pack('i',data))
 		# }}}
 
@@ -95,9 +95,9 @@
 		fid.write(struct.pack('i',8+4))  #1 double+code
 
-		#write data code: 
-		fid.write(struct.pack('i',FormatToCode(format))) 
+		#write data code:
+		fid.write(struct.pack('i',FormatToCode(format)))
 
 		#now write double
-		fid.write(struct.pack('d',data)) 
+		fid.write(struct.pack('d',data))
 		# }}}
 
@@ -106,10 +106,10 @@
 		fid.write(struct.pack('i',len(data)+4+4))  #string + string size + code
 
-		#write data code: 
-		fid.write(struct.pack('i',FormatToCode(format))) 
+		#write data code:
+		fid.write(struct.pack('i',FormatToCode(format)))
 
 		#now write string
-		fid.write(struct.pack('i',len(data))) 
-		fid.write(struct.pack('%ds' % len(data),data)) 
+		fid.write(struct.pack('i',len(data)))
+		fid.write(struct.pack('%ds' % len(data),data))
 		# }}}
 
@@ -135,17 +135,17 @@
 		fid.write(struct.pack('i',4+4+8*np.product(s)+4+4))    #2 integers (32 bits) + the double matrix + code + matrix type
 
-		#write data code and matrix type: 
-		fid.write(struct.pack('i',FormatToCode(format))) 
+		#write data code and matrix type:
+		fid.write(struct.pack('i',FormatToCode(format)))
 		fid.write(struct.pack('i',mattype))
 
 		#now write matrix
 		if np.ndim(data)==1:
-			fid.write(struct.pack('i',s[0])) 
-			fid.write(struct.pack('i',1)) 
+			fid.write(struct.pack('i',s[0]))
+			fid.write(struct.pack('i',1))
 			for i in xrange(s[0]):
 				fid.write(struct.pack('d',float(data[i])))    #get to the "c" convention, hence the transpose
 		else:
-			fid.write(struct.pack('i',s[0])) 
-			fid.write(struct.pack('i',s[1])) 
+			fid.write(struct.pack('i',s[0]))
+			fid.write(struct.pack('i',s[1]))
 			for i in xrange(s[0]):
 				for j in xrange(s[1]):
@@ -174,17 +174,17 @@
 		fid.write(struct.pack('i',4+4+8*np.product(s)+4+4))    #2 integers (32 bits) + the double matrix + code + matrix type
 
-		#write data code and matrix type: 
-		fid.write(struct.pack('i',FormatToCode(format))) 
+		#write data code and matrix type:
+		fid.write(struct.pack('i',FormatToCode(format)))
 		fid.write(struct.pack('i',mattype))
 
 		#now write matrix
 		if np.ndim(data) == 1:
-			fid.write(struct.pack('i',s[0])) 
-			fid.write(struct.pack('i',1)) 
+			fid.write(struct.pack('i',s[0]))
+			fid.write(struct.pack('i',1))
 			for i in xrange(s[0]):
 				fid.write(struct.pack('d',float(data[i])))    #get to the "c" convention, hence the transpose
 		else:
-			fid.write(struct.pack('i',s[0])) 
-			fid.write(struct.pack('i',s[1])) 
+			fid.write(struct.pack('i',s[0]))
+			fid.write(struct.pack('i',s[1]))
 			for i in xrange(s[0]):
 				for j in xrange(s[1]):
@@ -217,17 +217,17 @@
 		fid.write(struct.pack('i',recordlength))  #2 integers (32 bits) + the double matrix + code + matrix type
 
-		#write data code and matrix type: 
-		fid.write(struct.pack('i',FormatToCode(format))) 
+		#write data code and matrix type:
+		fid.write(struct.pack('i',FormatToCode(format)))
 		fid.write(struct.pack('i',mattype))
 
 		#now write matrix
 		if np.ndim(data) == 1:
-			fid.write(struct.pack('i',s[0])) 
-			fid.write(struct.pack('i',1)) 
+			fid.write(struct.pack('i',s[0]))
+			fid.write(struct.pack('i',1))
 			for i in xrange(s[0]):
 				fid.write(struct.pack('d',float(data[i])))    #get to the "c" convention, hence the transpose
 		else:
-			fid.write(struct.pack('i',s[0])) 
-			fid.write(struct.pack('i',s[1])) 
+			fid.write(struct.pack('i',s[0]))
+			fid.write(struct.pack('i',s[1]))
 			for i in xrange(s[0]):
 				for j in xrange(s[1]):
@@ -266,6 +266,6 @@
 		fid.write(struct.pack('i',recordlength))  #2 integers (32 bits) + the matrix + code + matrix type
 
-		#write data code and matrix type: 
-		fid.write(struct.pack('i',FormatToCode(format))) 
+		#write data code and matrix type:
+		fid.write(struct.pack('i',FormatToCode(format)))
 		fid.write(struct.pack('i',mattype))
 
@@ -276,12 +276,12 @@
 
 		if rangeA == 0:
-			A = A*0 
-		else:
-			A = (A-offsetA)/rangeA*255. 
-		
+			A = A*0
+		else:
+			A = (A-offsetA)/rangeA*255.
+
 		#now write matrix
 		if np.ndim(data) == 1:
-			fid.write(struct.pack('i',s[0])) 
-			fid.write(struct.pack('i',1)) 
+			fid.write(struct.pack('i',s[0]))
+			fid.write(struct.pack('i',1))
 			fid.write(struct.pack('d',float(offsetA)))
 			fid.write(struct.pack('d',float(rangeA)))
@@ -292,6 +292,6 @@
 
 		elif np.product(s) > 0:
-			fid.write(struct.pack('i',s[0])) 
-			fid.write(struct.pack('i',s[1])) 
+			fid.write(struct.pack('i',s[0]))
+			fid.write(struct.pack('i',s[1]))
 			fid.write(struct.pack('d',float(offsetA)))
 			fid.write(struct.pack('d',float(rangeA)))
@@ -324,11 +324,11 @@
 
 		#write length of record
-		fid.write(struct.pack('i',recordlength)) 
-
-		#write data code: 
-		fid.write(struct.pack('i',FormatToCode(format))) 
+		fid.write(struct.pack('i',recordlength))
+
+		#write data code:
+		fid.write(struct.pack('i',FormatToCode(format)))
 
 		#write data, first number of records
-		fid.write(struct.pack('i',len(data))) 
+		fid.write(struct.pack('i',len(data)))
 
 		for matrix in data:
@@ -343,11 +343,11 @@
 
 			if np.ndim(matrix) == 1:
-				fid.write(struct.pack('i',s[0])) 
-				fid.write(struct.pack('i',1)) 
+				fid.write(struct.pack('i',s[0]))
+				fid.write(struct.pack('i',1))
 				for i in xrange(s[0]):
 					fid.write(struct.pack('d',float(matrix[i])))    #get to the "c" convention, hence the transpose
 			else:
-				fid.write(struct.pack('i',s[0])) 
-				fid.write(struct.pack('i',s[1])) 
+				fid.write(struct.pack('i',s[0]))
+				fid.write(struct.pack('i',s[1]))
 				for i in xrange(s[0]):
 					for j in xrange(s[1]):
@@ -363,16 +363,16 @@
 
 		#write length of record
-		fid.write(struct.pack('i',recordlength)) 
-
-		#write data code: 
-		fid.write(struct.pack('i',FormatToCode(format))) 
+		fid.write(struct.pack('i',recordlength))
+
+		#write data code:
+		fid.write(struct.pack('i',FormatToCode(format)))
 
 		#now write length of string array
-		fid.write(struct.pack('i',len(data))) 
+		fid.write(struct.pack('i',len(data)))
 
 		#now write the strings
 		for string in data:
-			fid.write(struct.pack('i',len(string))) 
-			fid.write(struct.pack('%ds' % len(string),string)) 
+			fid.write(struct.pack('i',len(string)))
+			fid.write(struct.pack('%ds' % len(string),string))
 		# }}}
 
@@ -383,6 +383,6 @@
 def FormatToCode(format): # {{{
 	"""
-	This routine takes the format string, and hardcodes it into an integer, which 
-	is passed along the record, in order to identify the nature of the dataset being 
+	This routine takes the format string, and hardcodes it into an integer, which
+	is passed along the record, in order to identify the nature of the dataset being
 	sent.
 	"""
Index: issm/trunk/src/wrappers/Chaco/Chaco.cpp
===================================================================
--- issm/trunk/src/wrappers/Chaco/Chaco.cpp	(revision 23389)
+++ issm/trunk/src/wrappers/Chaco/Chaco.cpp	(revision 23394)
@@ -47,13 +47,13 @@
 	/*Fetch Data*/
 	FetchChacoData(&nvtxs,&adjacency,&start,&ewgts,A_IN,EWGTS_IN);
-	FetchData(&vwgts,&nterms,VWGTS_IN); 
-	FetchData(&x,&nterms,X_IN); 
-	FetchData(&y,&nterms,Y_IN); 
-	FetchData(&z,&nterms,Z_IN); 
-	FetchData(&in_options,&nterms,OPTNS_IN); 
+	FetchData(&vwgts,&nterms,VWGTS_IN);
+	FetchData(&x,&nterms,X_IN);
+	FetchData(&y,&nterms,Y_IN);
+	FetchData(&z,&nterms,Z_IN);
+	FetchData(&in_options,&nterms,OPTNS_IN);
 	for (i=0;i<(nterms<10?nterms:10);i++) options[i]=in_options[i]; //copy in_options into default options
-	FetchData(&npart,NPARTS_IN); 
+	FetchData(&npart,NPARTS_IN);
 	//int * nparts=xNew<int>(1); nparts[0]=npart; //weird Chacox interface ain't it?
-	FetchData(&goal,&nterms,GOAL_IN); 
+	FetchData(&goal,&nterms,GOAL_IN);
 
 	/*Allocate output: */
Index: issm/trunk/src/wrappers/DistanceToMaskBoundary/DistanceToMaskBoundary.cpp
===================================================================
--- issm/trunk/src/wrappers/DistanceToMaskBoundary/DistanceToMaskBoundary.cpp	(revision 23389)
+++ issm/trunk/src/wrappers/DistanceToMaskBoundary/DistanceToMaskBoundary.cpp	(revision 23394)
@@ -43,5 +43,6 @@
 
 	/*Call core of computation: */
-	DistanceToMaskBoundaryx(&distance,x,y,mask,nods);
+	_error_("messing up with AD, is this fonction really used??");
+	//DistanceToMaskBoundaryx(&distance,x,y,mask,nods);
 
 	/*Write results: */
Index: issm/trunk/src/wrappers/IssmConfig/IssmConfig.cpp
===================================================================
--- issm/trunk/src/wrappers/IssmConfig/IssmConfig.cpp	(revision 23389)
+++ issm/trunk/src/wrappers/IssmConfig/IssmConfig.cpp	(revision 23394)
@@ -66,4 +66,14 @@
 	else if(strcmp(name,"_HAVE_M1QN3_")==0){
 		#ifdef _HAVE_M1QN3_
+		value = 1.;
+		#endif
+	}
+	else if(strcmp(name,"_HAVE_ADOLC_")==0){
+		#ifdef _HAVE_ADOLC_
+		value = 1.;
+		#endif
+	}
+	else if(strcmp(name,"_HAVE_CODIPACK_")==0){
+		#ifdef _HAVE_CODIPACK_
 		value = 1.;
 		#endif
Index: issm/trunk/src/wrappers/javascript/Makefile.am
===================================================================
--- issm/trunk/src/wrappers/javascript/Makefile.am	(revision 23389)
+++ issm/trunk/src/wrappers/javascript/Makefile.am	(revision 23394)
@@ -1,3 +1,3 @@
-AM_CPPFLAGS = @DAKOTAINCL@ @PETSCINCL@ @MPIINCL@ @SPOOLESINCL@ @METISINCL@ @TRIANGLEINCL@ @CHACOINCL@ @SCOTCHINCL@ @SHAPELIBINCL@ @AMPIINCL@
+AM_CPPFLAGS = @DAKOTAINCL@ @PETSCINCL@ @MPIINCL@ @SPOOLESINCL@ @METISINCL@ @TRIANGLEINCL@ @CHACOINCL@ @SCOTCHINCL@ @SHAPELIBINCL@ @AMPIINCL@ @ADJOINTMPIINCL@ @CODIPACKINCL@
 AUTOMAKE_OPTIONS = subdir-objects
 
Index: issm/trunk/src/wrappers/matlab/Makefile.am
===================================================================
--- issm/trunk/src/wrappers/matlab/Makefile.am	(revision 23389)
+++ issm/trunk/src/wrappers/matlab/Makefile.am	(revision 23394)
@@ -1,3 +1,3 @@
-AM_CPPFLAGS = @NEOPZINCL@ @DAKOTAINCL@ @MATLABINCL@ @PETSCINCL@ @MPIINCL@ @SPOOLESINCL@ @METISINCL@ @TRIANGLEINCL@ @CHACOINCL@ @SCOTCHINCL@ @SHAPELIBINCL@ @AMPIINCL@
+AM_CPPFLAGS = @NEOPZINCL@ @DAKOTAINCL@ @MATLABINCL@ @PETSCINCL@ @MPIINCL@ @SPOOLESINCL@ @METISINCL@ @TRIANGLEINCL@ @CHACOINCL@ @SCOTCHINCL@ @SHAPELIBINCL@ @AMPIINCL@ @ADJOINTMPIINCL@ @MEDIPACKINCL@ @CODIPACKINCL@
 AUTOMAKE_OPTIONS = subdir-objects
 
Index: issm/trunk/src/wrappers/python/Makefile.am
===================================================================
--- issm/trunk/src/wrappers/python/Makefile.am	(revision 23389)
+++ issm/trunk/src/wrappers/python/Makefile.am	(revision 23394)
@@ -1,3 +1,3 @@
-AM_CPPFLAGS = @DAKOTAINCL@ @PETSCINCL@ @MPIINCL@ @SPOOLESINCL@ @METISINCL@ @TRIANGLEINCL@ @CHACOINCL@ @SCOTCHINCL@ @SHAPELIBINCL@ @PYTHONINCL@ @PYTHON_NUMPYINCL@ @AMPIINCL@
+AM_CPPFLAGS = @DAKOTAINCL@ @PETSCINCL@ @MPIINCL@ @SPOOLESINCL@ @METISINCL@ @TRIANGLEINCL@ @CHACOINCL@ @SCOTCHINCL@ @SHAPELIBINCL@ @PYTHONINCL@ @PYTHON_NUMPYINCL@ @AMPIINCL@ @ADJOINTMPIINCL@ @MEDIPACKINCL@ @CODIPACKINCL@
 AUTOMAKE_OPTIONS = subdir-objects
 
Index: issm/trunk/src/wrappers/python/io/FetchPythonData.cpp
===================================================================
--- issm/trunk/src/wrappers/python/io/FetchPythonData.cpp	(revision 23389)
+++ issm/trunk/src/wrappers/python/io/FetchPythonData.cpp	(revision 23394)
@@ -32,5 +32,5 @@
 	}
 	else if (PyInt_Check(py_float))
-	 dscalar=(double)PyInt_AsLong(py_float);
+		dscalar=(double)PyInt_AsLong(py_float);
 	else if (PyBool_Check(py_float))
 		dscalar=(double)PyLong_AsLong(py_float);
@@ -132,5 +132,6 @@
 	double* dmatrix=NULL;
 	double* matrix=NULL;
-	int M,N;
+	int M=0;
+	int N=0;
 	int ndim;
 	npy_intp*  dims=NULL;
@@ -236,5 +237,6 @@
 	/*output: */
 	int* matrix=NULL;
-	int M,N;
+	int M=0;
+	int N=0;
 	int ndim;
 	npy_intp*  dims=NULL;
@@ -325,5 +327,6 @@
 	bool* bmatrix=NULL;
 	bool* matrix=NULL;
-	int M,N;
+	int M=0;
+	int N=0;
 	int ndim;
 	npy_intp*  dims=NULL;
@@ -411,5 +414,5 @@
 	double* dvector=NULL;
 	double* vector=NULL;
-	int M;
+	int M=0;
 	int ndim;
 	npy_intp*  dims=NULL;
@@ -499,5 +502,5 @@
 	/*output: */
 	float* vector=NULL;
-	int M;
+	int M=0;
 	int ndim;
 	npy_intp*  dims=NULL;
@@ -539,5 +542,5 @@
 				/*transform into int vector: */
 				vector=xNew<float>(M);
-				for(i=0;i<M;i++)vector[i]=(float)lvector[i];
+				for(i=0;i<M;i++)vector[i]=(float)dvector[i];
 			}
 
@@ -566,5 +569,5 @@
 		}
 		else
-		 vector=NULL;
+			vector=NULL;
 	}
 	else{
@@ -584,5 +587,5 @@
 	/*output: */
 	int* vector=NULL;
-	int M;
+	int M=0;
 	int ndim;
 	npy_intp*  dims=NULL;
@@ -624,5 +627,5 @@
 				/*transform into int vector: */
 				vector=xNew<int>(M);
-				for(i=0;i<M;i++)vector[i]=(int)lvector[i];
+				for(i=0;i<M;i++)vector[i]=(int)dvector[i];
 			}
 
@@ -672,5 +675,5 @@
 	bool* bvector=NULL;
 	bool* vector=NULL;
-	int M;
+	int M=0;
 	int ndim;
 	npy_intp*  dims=NULL;
@@ -923,8 +926,88 @@
 	*pcontours=contours;
 }
-/*}}}*/
-void FetchChacoData(int* pnvtxs,int** padjacency,int** pstart,float** pewgts,PyObject* A_IN,PyObject* EWGTS_IN){
-	_error_("Nathan... I need your help here");
-}
+
+void FetchChacoData(int* pnvtxs,int** padjacency,int** pstart,float** pewgts,PyObject* A_IN, PyObject* EWGTS_IN){/*{{{*/
+
+	double* a = ((double*)PyArray_DATA((PyArrayObject*)A_IN));
+	int ndim  = PyArray_NDIM((PyArrayObject*)A_IN);
+	int nzmax = PyArray_CountNonzero((PyArrayObject*)A_IN);
+
+	/*Fetch adjacency matrix:*/
+	int      nvtxs       = PyArray_DIMS((PyArrayObject*)A_IN)[1];
+
+	int* mwstart = xNewZeroInit<int>(nvtxs+1);
+	pyGetJc(a,nvtxs,mwstart);
+
+	int* mwadjacency = xNewZeroInit<int>(nzmax);
+	pyGetIr(a,nvtxs,nzmax,mwadjacency);
+	
+	int* start = xNew<int>(nvtxs+1);
+	for(int i=0;i<nvtxs+1;i++) start[i]=(int)mwstart[i];
+	int* adjacency = xNew<int>(nzmax);
+	for(int i=0; i<nzmax; i++) adjacency[i]=(int)mwadjacency[i];
+
+	/*Get edges weights*/
+	int nedges = start[nvtxs];
+	float* ewgts = NULL;
+	int size = PyArray_SIZE((PyArrayObject*)EWGTS_IN);
+	//size may be 1 and still be empty;
+	//presumably size of edge_weights input will never be exactly 1
+	if(size != 1 && size != 0){
+		ewgts = xNewZeroInit<float>(nedges);
+		for(int i = 0; i<nedges;i++){
+			ewgts[i] = (float)a[i];
+		}
+	}
+
+	/*Assign output pointers*/
+	*pnvtxs     = nvtxs;
+	*padjacency = adjacency;
+	*pstart     = start;
+	*pewgts     = ewgts;
+}
+/*}}}*/
+
+void pyGetJc(double* a, int nvtxs, int* Jc){
+/*{{{*/
+	//get the number of non-zero elements in each row, adding to the prior number;
+	//always starts with 0 and has length: number_of_rows_in(a)+1 == nvtxs+1
+	// eg: 0, 1, 3, 6, 8, 13, ...
+	// for: 1 in the first row, 2 in the second, 3 in the third, etc.
+	int c = 0;
+	Jc[c++] = 0;
+
+	for(int i=0;i<nvtxs;i++){
+		for(int j=0;j<nvtxs;j++){
+			if ((int)a[i+(j*nvtxs)] != 0){
+				Jc[c] += 1;
+			}
+		}
+		c++;
+		Jc[c] = Jc[c-1];
+	}
+	return;
+}
+/*}}}*/
+
+void pyGetIr(double* a, int nvtxs, int nzmax, int* Ir){
+/*{{{*/
+	//get the row-wise position of each non-zero element;
+	//has length: number_of_non_zero_elements_in(a) == nzmax
+	// eg: 10, 24, 25, 4, ...
+	// the 10th, 24th, and 25th elements in the first row, the 4th in the second row
+	// using pyGetJc to determine which indices correspond to which row
+	int r = 0;
+
+	for(int i=0;i<nvtxs;i++){
+		for(int j=0;j<nvtxs;j++){
+			if ((int)a[i+(j*nvtxs)] != 0){
+				Ir[r] = j;
+				r++;
+			}
+		}
+	}
+	return;
+}
+/*}}}*/
 
 /*Python version dependent: */
Index: issm/trunk/src/wrappers/python/io/pythonio.h
===================================================================
--- issm/trunk/src/wrappers/python/io/pythonio.h	(revision 23389)
+++ issm/trunk/src/wrappers/python/io/pythonio.h	(revision 23394)
@@ -51,4 +51,7 @@
 void FetchChacoData(int* pnvtxs,int** padjacency,int** pstart,float** pewgts,PyObject* A_IN,PyObject* EWGTS_IN);
 
+void pyGetJc(double* a, int nvtxs, int* Jc);
+void pyGetIr(double* a, int nvtxs, int nzmax, int* Ir);
+
 int CheckNumPythonArguments(PyObject* inputs,int NRHS, void (*function)( void ));
 
Index: issm/trunk/test/NightlyRun/runme.py
===================================================================
--- issm/trunk/test/NightlyRun/runme.py	(revision 23389)
+++ issm/trunk/test/NightlyRun/runme.py	(revision 23394)
@@ -11,5 +11,5 @@
 	"""
 	RUNME - test deck for ISSM nightly runs
- 
+
 	    In a test deck directory (tests/Vertification/NightlyRun for example)
 	    The following command will launch all the existing tests:
@@ -18,5 +18,5 @@
 	    >> runme(id=[101,102])
 	    etc...
- 
+
 	    Available options:
 	       'id'            followed by the list of ids or (parts of) test names requested
@@ -37,8 +37,8 @@
 	       'procedure'     'check' : run the test (default)
 	                       'update': update the archive
- 
+
 	    Usage:
 	       runme(varargin)
- 
+
 	    Examples:
 	       runme()
@@ -49,5 +49,4 @@
 	       runme(id=[[101,102],['Dakota','Slr']])
 	"""
-
 	from parallelrange import parallelrange
 	from IdToName import IdToName
@@ -82,17 +81,14 @@
 	flist=glob('test*.py')    #File name must start with 'test' and must end by '.py' and must be different than 'test.py'
 	list_ids=[int(file[4:-3]) for file in flist if not file == 'test.py']    #Keep test id only (skip 'test' and '.py')
-	#print 'list_ids =',list_ids
 
 	i1,i2=parallelrange(rank,numprocs,len(list_ids))    #Get tests for this cpu only
 	list_ids=list_ids[i1:i2+1]
-	#print 'list_ids after parallelrange =',list_ids
-	
-	if id:
+
+	if np.size(id) > 0 and not id==None:
 		test_ids = set(GetIds(id)).intersection(set(list_ids))
 	else:
 		# if no tests are specifically provided, do them all
 		test_ids = set(list_ids)
-		
-	#print 'test_ids after list =',test_ids
+
 	# }}}
 	#GET exclude {{{
@@ -100,6 +96,4 @@
 
 	test_ids=test_ids.difference(exclude_ids)
-	#print 'test_ids after exclude =',sorted(test_ids)
-	#return
 	# }}}
 	#Process Ids according to benchmarks {{{
@@ -124,8 +118,6 @@
 	elif benchmark=='adolc':
 		test_ids=test_ids.intersection(set(range(3001,3200)))
-	#print 'test_ids after benchmark =',test_ids
 	test_ids=list(test_ids)
 	test_ids.sort()
-	#print 'test_ids after sort =',test_ids
 	# }}}
 
@@ -190,5 +182,5 @@
 							if np.shape(field) != np.shape(archive):
 								raise RuntimeError("Field '"+archive_name+"' from test is malformed; shape is "+str(np.shape(field.T))+", should be "+str(np.shape(archive))+" (or "+str(np.shape(archive.T))+").")
-						
+
 						error_diff=np.amax(np.abs(archive-field),axis=0)/(np.amax(np.abs(archive),axis=0)+float_info.epsilon)
 
Index: issm/trunk/test/NightlyRun/test2084.m
===================================================================
--- issm/trunk/test/NightlyRun/test2084.m	(revision 23389)
+++ issm/trunk/test/NightlyRun/test2084.m	(revision 23394)
@@ -1,4 +1,3 @@
-
-%Test Name: GiaCaron. 
+%Test Name: GiaCaron
 %Forward Love number solution for a viscoelastic earth, model M3-L70-V01 from
 %Spada, G., Barletta, V. R., Klemann, V., Riva, R. E. M., Martinec, Z.,
@@ -39,5 +38,5 @@
 %loading love numbers
 field_names     ={'LoveH_loading_elastic','LoveK_loading_elastic','LoveL_loading_elastic'};
-field_tolerances={7.0e-10,7.0e-10,7.0e-10};
+field_tolerances={4.3e-9,4.3e-9,4.3e-9};
 field_values={...
 	(md.results.LoveSolution.LoveHr(:,1)),...
@@ -57,5 +56,5 @@
 %Fields and tolerances to track changes
 field_names     ={field_names{:},'LoveH_loading_realpart','LoveK_loading_realpart','LoveL_loading_realpart','LoveH_loading_imagpart','LoveK_loading_imagpart','LoveL_loading_imagpart'};
-field_tolerances={field_tolerances{:},7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10};
+field_tolerances={field_tolerances{:},5e-7,5e-7,5e-7,5e-7,5e-7,5e-7};
 field_values={field_values{:},...
 	(md.results.LoveSolution.LoveHr(:,:)),...
@@ -75,5 +74,5 @@
 %tidal love numbers
 field_names     ={field_names{:},'LoveH_tidal_elastic','LoveK_tidal_elastic','LoveL_tidal_elastic','LoveH_tidal_realpart','LoveK_tidal_realpart','LoveL_tidal_realpart','LoveH_tidal_imagpart','LoveK_tidal_imagpart','LoveL_tidal_imagpart'};
-field_tolerances={field_tolerances{:},7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10};
+field_tolerances={field_tolerances{:},8e-6,8e-6,8e-6,8e-6,8e-6,8e-6,8e-6,8e-6,8e-6};
 field_values={field_values{:},...
 	(md.results.LoveSolution.LoveHr(:,1)),...
@@ -115,5 +114,5 @@
 %
 %field_names     ={field_names{:},'LoveH_loadingVSS96_elastic','LoveK_loadingVSS96_elastic','LoveL_loadingVSS96_elastic','LoveH_loadingVSS96_realpart','LoveK_loadingVSS96_realpart','LoveL_loadingVSS96_realpart','LoveH_loadingVSS96_imagpart','LoveK_loadingVSS96_imagpart','LoveL_loadingVSS96_imagpart'};
-%field_tolerances={field_tolerances{:},7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10};
+%field_tolerances={field_tolerances{:},2e-6,2e-6,2e-6,2e-6,2e-6,2e-6,2e-6,2e-6,2e-6};
 %field_values={field_values{:},...
 %	(md.results.LoveSolution.LoveHr(:,1)),...
@@ -147,5 +146,5 @@
 
 field_names     ={field_names{:},'LoveH_loadingVSS96_elastic','LoveK_loadingVSS96_elastic','LoveL_loadingVSS96_elastic','LoveH_loadingVSS96_realpart','LoveK_loadingVSS96_realpart','LoveL_loadingVSS96_realpart','LoveH_loadingVSS96_imagpart','LoveK_loadingVSS96_imagpart','LoveL_loadingVSS96_imagpart'};
-field_tolerances={field_tolerances{:},7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10,7.0e-10};
+field_tolerances={field_tolerances{:},2e-6,2e-6,2e-6,2e-6,2e-6,2e-6,2e-6,2e-6,2e-6};
 field_values={field_values{:},...
 	(md.results.LoveSolution.LoveHr(:,1)),...
Index: issm/trunk/test/NightlyRun/test2084.py
===================================================================
--- issm/trunk/test/NightlyRun/test2084.py	(revision 23389)
+++ issm/trunk/test/NightlyRun/test2084.py	(revision 23394)
@@ -1,8 +1,9 @@
-#Test Name: GiaCaron. Forward Love number solution for a viscoelastic earth,
-#	model M3-L70-V01 from Spada, G., Barletta, V. R., Klemann, V., Riva, R. E. M.,
-#	Martinec, Z., Gasperini, P., Lund, B., Wolf, D., Vermeersen, L. L. A.
-#	and King, M. A. (2011), A benchmark study for glacial isostatic
-#	adjustment codes. Geophysical Journal International,
-#	185: 106-132. doi:10.1111/j.1365-246X.2011.04952.x
+#Test Name: GiaCaron
+#Forward Love number solution for a viscoelastic earth,
+#model M3-L70-V01 from Spada, G., Barletta, V. R., Klemann, V., Riva, R. E. M.,
+#Martinec, Z., Gasperini, P., Lund, B., Wolf, D., Vermeersen, L. L. A.
+#and King, M. A. (2011), A benchmark study for glacial isostatic
+#adjustment codes. Geophysical Journal International,
+#185: 106-132. doi:10.1111/j.1365-246X.2011.04952.x
 
 from model import *
@@ -48,6 +49,6 @@
 #Fields and tolerances to track changes
 #loading love numbers
-field_names=['LoveHe','LoveKe','LoveLe']
-field_tolerances=[3.7e-9,3.7e-9,3.7e-9]
+field_names=['LoveH_loading_elastic','LoveK_loading_elastic','LoveL_loading_elastic']
+field_tolerances=[4.3e-9,4.3e-9,4.3e-9]
 field_values=[
 np.array(md.results.LoveSolution.LoveHr)[:,0],
@@ -67,6 +68,6 @@
 #Fields and tolerances to track changes
 #loading love numbers
-field_names+=['LoveHlr','LoveKlr','LoveLlr','LoveHli','LoveKli','LoveLli']
-field_tolerances+=[3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9]
+field_names+=['LoveH_loading_realpart','LoveK_loading_realpart','LoveL_loading_realpart','LoveH_loading_imagpart','LoveK_loading_imagpart','LoveL_loading_imagpart']
+field_tolerances+=[5e-7,5e-7,5e-7,5e-7,5e-7,5e-7]
 field_values+=[
 np.array(md.results.LoveSolution.LoveHr),
@@ -87,6 +88,6 @@
 
 #tidal love numbers, check
-field_names+=['LoveHtr','LoveKtr','LoveLtr','LoveHti','LoveKti','LoveLti']
-field_tolerances+=[3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9]
+field_names+=['LoveH_tidal_elastic','LoveK_tidal_elastic','LoveL_tidal_elastic','LoveH_tidal_realpart','LoveK_tidal_realpart','LoveL_tidal_realpart','LoveH_tidal_imagpart','LoveK_tidal_imagpart','LoveL_tidal_imagpart']
+field_tolerances+=[8e-6,8e-6,8e-6,8e-6,8e-6,8e-6,8e-6,8e-6,8e-6]
 field_values+=[
 np.array(md.results.LoveSolution.LoveHr)[:,0],
@@ -127,6 +128,6 @@
 #md=solve(md,'lv')
 #
-#field_names=[field_names,'LoveHmr','LoveKmr','LoveLmr','LoveHmi','LoveKmi','LoveLmi']
-#field_tolerances=[field_tolerances,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13]
+#field_names=[field_names,'LoveH_loadingVSS96_elastic','LoveK_loadingVSS96_elastic','LoveL_loadingVSS96_elastic','LoveH_loadingVSS96_realpart','LoveK_loadingVSS96_realpart','LoveL_loadingVSS96_realpart','LoveH_loadingVSS96_imagpart','LoveK_loadingVSS96_imagpart','LoveL_loadingVSS96_imagpart']
+#field_tolerances=[field_tolerances,4.3e-9,4.3e-9,4.3e-9,4.3e-9,4.3e-9,4.3e-9,4.3e-9,4.3e-9,4.3e-9]
 #field_values=[field_values,\
 #	(md.results.LoveSolution.LoveHr[:][0]),\
@@ -186,6 +187,6 @@
 md.love.nfreq=len(md.love.frequencies)
 
-field_names+=['LoveHmr','LoveKmr','LoveLmr','LoveHmi','LoveKmi','LoveLmi']
-field_tolerances+=[3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9,3.7e-9]
+field_names+=['LoveH_loadingVSS96_elastic','LoveK_loadingVSS96_elastic','LoveL_loadingVSS96_elastic','LoveH_loadingVSS96_realpart','LoveK_loadingVSS96_realpart','LoveL_loadingVSS96_realpart','LoveH_loadingVSS96_imagpart','LoveK_loadingVSS96_imagpart','LoveL_loadingVSS96_imagpart']
+field_tolerances+=[2e-6,2e-6,2e-6,2e-6,2e-6,2e-6,2e-6,2e-6,2e-6]
 field_values+=[
 np.array(md.results.LoveSolution.LoveHr)[:,0],
Index: issm/trunk/test/NightlyRun/test211.js
===================================================================
--- issm/trunk/test/NightlyRun/test211.js	(revision 23389)
+++ issm/trunk/test/NightlyRun/test211.js	(revision 23394)
@@ -12,10 +12,10 @@
 //Fields and tolerances to track changes
 field_names=[
-	'Vx1','Vy1','Vz1','Vel1','Pressure1','Bed1','Surface1','Thickness1','Temperature1','BasalforcingsGroundediceMeltingRate1', 
-	'Vx2','Vy2','Vz2','Vel2','Pressure2','Bed2','Surface2','Thickness2','Temperature2','BasalforcingsGroundediceMeltingRate2', 
+	'Vx1','Vy1','Vz1','Vel1','Pressure1','Bed1','Surface1','Thickness1','Temperature1','BasalforcingsGroundediceMeltingRate1',
+	'Vx2','Vy2','Vz2','Vel2','Pressure2','Bed2','Surface2','Thickness2','Temperature2','BasalforcingsGroundediceMeltingRate2',
 	'Vx3','Vy3','Vz3','Vel3','Pressure3','Bed3','Surface3','Thickness3','Temperature3','BasalforcingsGroundediceMeltingRate3'];
 field_tolerances=[
 	2e-08,2e-08,5e-05,2e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,
-	5e-06,5e-06,8e-05,5e-06,1e-07,5e-07,5e-07,5e-07,3e-06,5e-05,
+	5e-06,5e-06,8e-05,5e-06,5e-07,5e-07,5e-07,5e-07,3e-06,5e-05,
 	8e-06,8e-06,8e-05,8e-06,5e-07,8e-07,8e-07,8e-07,5e-06,8e-05];
 field_values=[
Index: issm/trunk/test/NightlyRun/test211.m
===================================================================
--- issm/trunk/test/NightlyRun/test211.m	(revision 23389)
+++ issm/trunk/test/NightlyRun/test211.m	(revision 23394)
@@ -16,5 +16,5 @@
 field_tolerances={...
 	2e-08,2e-08,5e-05,2e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,...
-	5e-06,5e-06,8e-05,5e-06,1e-07,5e-07,5e-07,5e-07,3e-06,5e-05,...
+	5e-06,5e-06,8e-05,5e-06,5e-07,5e-07,5e-07,5e-07,3e-06,5e-05,...
 	8e-06,8e-06,8e-05,8e-06,5e-07,8e-07,8e-07,8e-07,5e-06,8e-05};
 field_values={...
Index: issm/trunk/test/NightlyRun/test211.py
===================================================================
--- issm/trunk/test/NightlyRun/test211.py	(revision 23389)
+++ issm/trunk/test/NightlyRun/test211.py	(revision 23394)
@@ -26,6 +26,6 @@
 						 'Vx3','Vy3','Vz3','Vel3','Pressure3','Bed3','Surface3','Thickness3','Temperature3','BasalforcingsGroundediceMeltingRate3']
 field_tolerances=[2e-08,2e-08,5e-05,2e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,
-									5e-06,5e-06,8e-05,5e-06,1e-07,5e-07,5e-07,5e-07,3e-06,5e-05,
-									8e-06,8e-06,8e-05,8e-06,5e-07,8e-07,8e-07,8e-07,5e-06,8e-05]
+        5e-06,5e-06,8e-05,5e-06,5e-07,5e-07,5e-07,5e-07,3e-06,5e-05,
+        8e-06,8e-06,8e-05,8e-06,5e-07,8e-07,8e-07,8e-07,5e-06,8e-05]
 field_values=[md.results.TransientSolution[0].Vx,
 							md.results.TransientSolution[0].Vy,
Index: issm/trunk/test/NightlyRun/test215.m
===================================================================
--- issm/trunk/test/NightlyRun/test215.m	(revision 23389)
+++ issm/trunk/test/NightlyRun/test215.m	(revision 23394)
@@ -24,5 +24,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Gradient','Misfits','MaterialsRheologyBbar','Pressure','Vel','Vx','Vy'};
-field_tolerances={4.6e-08,1e-08,2e-08,1e-09,2e-09,2e-08,2e-08};
+field_tolerances={4.6e-08,1e-08,2e-08,2e-09,3e-09,2e-08,2e-08};
 field_values={...
 	(md.results.StressbalanceSolution.Gradient1),...
Index: issm/trunk/test/NightlyRun/test215.py
===================================================================
--- issm/trunk/test/NightlyRun/test215.py	(revision 23389)
+++ issm/trunk/test/NightlyRun/test215.py	(revision 23394)
@@ -37,5 +37,5 @@
 # Fields and tolerances to track changes
 field_names     =['Gradient','Misfits','MaterialsRheologyBbar','Pressure','Vel','Vx','Vy']
-field_tolerances=[4.6e-08,1e-08,2e-09,1e-08,2e-09,2e-08,2e-08]
+field_tolerances=[4.6e-08,1e-08,2e-08,2e-09,3e-09,2e-08,2e-08]
 field_values=[md.results.StressbalanceSolution.Gradient1,
         md.results.StressbalanceSolution.J,
Index: issm/trunk/test/NightlyRun/test234.py
===================================================================
--- issm/trunk/test/NightlyRun/test234.py	(revision 23394)
+++ issm/trunk/test/NightlyRun/test234.py	(revision 23394)
@@ -0,0 +1,101 @@
+#Test Name: SquareShelfTranForceNeg2dDakotaSamp
+import numpy as np
+import scipy.io as spio
+from os import getcwd
+from model import *
+from socket import gethostname
+from triangle import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from solve import *
+from SMBgemb import *
+from partitioner import *
+from dmeth_params_set import *
+
+md = triangle(model(),'../Exp/Square.exp',180000.)
+md = setmask(md,'all','')
+md = parameterize(md,'../Par/SquareShelf.py')
+md = setflowequation(md,'SSA','all')
+md.cluster = generic('name',gethostname(),'np',3)
+
+md.timestepping.time_step = 1
+md.settings.output_frequency = 1
+md.timestepping.final_time = 4
+
+smb = np.ones((md.mesh.numberofvertices,))*3.6
+smb = np.array([smb,smb*-1]).T
+
+md.smb.mass_balance = smb
+md.smb.mass_balance = np.concatenate((md.smb.mass_balance,[[1.5,3]]))
+md.transient.isthermal = 0
+
+#Dakota options
+
+#dakota version
+version = IssmConfig('_DAKOTA_VERSION_')
+version = float(version[0])
+
+#partitioning
+md.qmu.numberofpartitions = 20
+md = partitioner(md,'package','chaco','npart',md.qmu.numberofpartitions,'weighting','on')
+md.qmu.partition = md.qmu.partition - 1
+
+#variables
+md.qmu.variables.surface_mass_balance = normal_uncertain.normal_uncertain('scaled_SmbMassBalance',1,0.1)
+
+#responses
+md.qmu.responses.MaxVel = response_function.response_function('MaxVel',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.IceVolume = response_function.response_function('IceVolume',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux1 = response_function.response_function('indexed_MassFlux_1',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux2 = response_function.response_function('indexed_MassFlux_2',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux3 = response_function.response_function('indexed_MassFlux_3',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux4 = response_function.response_function('indexed_MassFlux_4',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux5 = response_function.response_function('indexed_MassFlux_5',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.massFlux6 = response_function.response_function('indexed_MassFlux_6',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+
+#mass flux profiles
+md.qmu.mass_flux_profiles = ['../Exp/MassFlux1.exp','../Exp/MassFlux2.exp','../Exp/MassFlux3.exp','../Exp/MassFlux4.exp','../Exp/MassFlux5.exp','../Exp/MassFlux6.exp']
+md.qmu.mass_flux_profile_directory = getcwd()
+
+##  nond_sampling study
+md.qmu.method = dakota_method.dakota_method('nond_samp')
+md.qmu.method = dmeth_params_set(md.qmu.method,'seed',1234,'samples',20,'sample_type','lhs')
+dver = str(version)
+if ((int(dver[0]) == 4 and int(dver[2])>2) or int(dver[0])>4):
+	md.qmu.method = dmeth_params_set(md.qmu.method,'rng','rnum2')
+
+#parameters
+md.qmu.params.direct = True
+md.qmu.params.analysis_components = ''
+md.qmu.params.interval_type = 'forward'
+md.qmu.params.tabular_graphics_data = True
+md.qmu.isdakota = 1
+
+if version >= 6:
+	md.qmu.params.analysis_driver = 'matlab'
+	md.qmu.params.evaluation_scheduling = 'master'
+	md.qmu.params.processors_per_evaluation = 2
+else:
+	md.qmu.params.analysis_driver = 'stressbalance'
+	md.qmu.params.evaluation_concurrency = 1
+
+md.stressbalance.reltol = 10**-5 #tighten for qmu analyses
+md.transient.requested_outputs = ['IceVolume']
+
+#solve
+md.verbose = verbose('000000000')	# this line is recommended
+md = solve(md,'Transient','overwrite','y')
+md.qmu.results = md.results.dakota
+
+#Fields and tolerances to track changes
+md.results.dakota.moments = []
+for i in range(8):
+	md.results.dakota.moments.append(md.results.dakota.dresp_out[i].mean)
+
+for i in range(8):
+	md.results.dakota.moments.append(md.results.dakota.dresp_out[i].stddev)
+
+field_names      = ['moments']
+field_tolerances = [1e-11]
+field_values = [md.results.dakota.moments]
Index: issm/trunk/test/NightlyRun/test235.py
===================================================================
--- issm/trunk/test/NightlyRun/test235.py	(revision 23394)
+++ issm/trunk/test/NightlyRun/test235.py	(revision 23394)
@@ -0,0 +1,97 @@
+#Test Name: SquareShelfTranForceNeg2dDakotaLocal
+import numpy as np
+import scipy.io as spio
+from os import getcwd
+from model import *
+from socket import gethostname
+from triangle import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from solve import *
+from SMBgemb import *
+from partitioner import *
+from dmeth_params_set import *
+
+md = triangle(model(),'../Exp/Square.exp',180000.)
+md = setmask(md,'all','')
+md = parameterize(md,'../Par/SquareShelf.py')
+md = setflowequation(md,'SSA','all')
+md.cluster = generic('name',gethostname(),'np',3)
+
+md.timestepping.time_step = 1
+md.settings.output_frequency = 1
+md.timestepping.final_time = 4
+
+smb = np.ones((md.mesh.numberofvertices,))*3.6
+smb = np.array([smb,smb*-1]).T
+
+md.smb.mass_balance = smb
+md.smb.mass_balance = np.concatenate((md.smb.mass_balance,[[1.5,3]]))
+md.transient.isthermal = 0
+
+#Dakota options
+
+#dakota version
+version = IssmConfig('_DAKOTA_VERSION_')
+version = float(version[0])
+
+#partitioning
+md.qmu.numberofpartitions = 20
+md = partitioner(md,'package','chaco','npart',md.qmu.numberofpartitions,'weighting','on')
+md.qmu.partition = md.qmu.partition - 1
+
+#variables
+md.qmu.variables.surface_mass_balance = normal_uncertain.normal_uncertain('scaled_SmbMassBalance',1,100)
+
+#responses
+md.qmu.responses.MaxVel = response_function.response_function('MaxVel',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.IceVolume = response_function.response_function('IceVolume',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux1 = response_function.response_function('indexed_MassFlux_1',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux2 = response_function.response_function('indexed_MassFlux_2',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux3 = response_function.response_function('indexed_MassFlux_3',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux4 = response_function.response_function('indexed_MassFlux_4',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux5 = response_function.response_function('indexed_MassFlux_5',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.massFlux6 = response_function.response_function('indexed_MassFlux_6',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+
+#mass flux profiles
+md.qmu.mass_flux_profiles = ['../Exp/MassFlux1.exp','../Exp/MassFlux2.exp','../Exp/MassFlux3.exp','../Exp/MassFlux4.exp','../Exp/MassFlux5.exp','../Exp/MassFlux6.exp']
+md.qmu.mass_flux_profile_directory = getcwd()
+
+#method
+md.qmu.method = dakota_method.dakota_method('nond_l')
+
+#parameters
+md.qmu.params.direct = True
+md.qmu.params.analysis_components = ''
+md.qmu.params.interval_type = 'forward'
+md.qmu.params.fd_gradient_step_size = '0.1'
+md.qmu.isdakota = 1
+
+if version >= 6:
+	md.qmu.params.analysis_driver = 'matlab'
+	md.qmu.params.evaluation_scheduling = 'master'
+	md.qmu.params.processors_per_evaluation = 2
+else:
+	md.qmu.params.analysis_driver = 'stressbalance'
+	md.qmu.params.evaluation_concurrency = 1
+
+md.stressbalance.reltol = 10**-5 #tighten for qmu analyses
+md.transient.requested_outputs = ['IceVolume']
+
+#solve
+md.verbose = verbose('000000000')	# this line is recommended
+md = solve(md,'Transient','overwrite','y')
+md.qmu.results = md.results.dakota
+
+#Fields and tolerances to track changes
+md.results.dakota.moments = []
+for i in range(8):
+	md.results.dakota.moments.append(md.results.dakota.dresp_out[i].mean)
+
+for i in range(8):
+	md.results.dakota.moments.append(md.results.dakota.dresp_out[i].stddev)
+
+field_names      = ['moments']
+field_tolerances = [1e-11]
+field_values = [md.results.dakota.moments]
Index: issm/trunk/test/NightlyRun/test245.m
===================================================================
--- issm/trunk/test/NightlyRun/test245.m	(revision 23394)
+++ issm/trunk/test/NightlyRun/test245.m	(revision 23394)
@@ -0,0 +1,47 @@
+%Test Name: SquareShelfTranIspddSicopolisSSA2d
+md=triangle(model(),'../Exp/Square.exp',150000.);
+md=setmask(md,'all','');
+md=parameterize(md,'../Par/SquareShelf.par');
+
+% Use of SMBpddSicopolis
+md.smb = SMBpddSicopolis();
+% initalize pdd fields
+md.smb=initialize(md.smb,md);
+md.smb.s0p=md.geometry.surface;
+md.smb.s0t=md.geometry.surface;
+
+% 
+md.smb.monthlytemperatures=[]; md.smb.precipitation=[]; md.smb.precipitation=[];
+temp_ma_present=-10*ones(md.mesh.numberofvertices,1)-md.smb.rlaps*md.geometry.surface/1000;
+temp_mj_present=10*ones(md.mesh.numberofvertices,1)-md.smb.rlaps*md.geometry.surface/1000;
+precipitation=5*ones(md.mesh.numberofvertices,1);
+for imonth=0:11
+    md.smb.monthlytemperatures(1:md.mesh.numberofvertices,imonth+1)=md.materials.meltingpoint+temp_ma_present+(temp_mj_present-temp_ma_present)*sin(double(imonth+1-4)*pi/6.0);
+    md.smb.monthlytemperatures(md.mesh.numberofvertices+1,imonth+1)=((imonth+1)/12);
+    md.smb.precipitation(1:md.mesh.numberofvertices,imonth+1)=precipitation;
+    md.smb.precipitation(md.mesh.numberofvertices+1,imonth+1)=((imonth+1)/12);
+end
+
+% time steps and resolution
+md.timestepping.time_step=1;
+md.settings.output_frequency=1;
+md.timestepping.final_time=2;
+
+md.transient.issmb=1;
+md.transient.ismasstransport=1;
+md.transient.isstressbalance=0;
+md.transient.isthermal=0;
+
+md.transient.requested_outputs={'default','TemperaturePDD'};
+md.cluster=generic('name',oshostname(),'np',1); % 3 for the cluster
+md=solve(md,'Transient');
+
+%Fields and tolerances to track changes
+field_names     ={'TemperaturePDD1','SmbMassBalance1','TemperaturePDD2','SmbMassBalance2'};
+field_tolerances={1e-13,1e-13,1e-13,1e-13};
+field_values={...
+	(md.results.TransientSolution(1).TemperaturePDD),...
+	(md.results.TransientSolution(1).SmbMassBalance),...
+	(md.results.TransientSolution(2).TemperaturePDD),...
+	(md.results.TransientSolution(2).SmbMassBalance),...
+	};
Index: issm/trunk/test/NightlyRun/test245.py
===================================================================
--- issm/trunk/test/NightlyRun/test245.py	(revision 23394)
+++ issm/trunk/test/NightlyRun/test245.py	(revision 23394)
@@ -0,0 +1,59 @@
+#Test Name: SquareShelfTranIspddSicopolisSSA2d
+import numpy as np
+from model import *
+from socket import gethostname
+from triangle import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from solve import *
+
+from SMBpddSicopolis import *
+
+md = triangle(model(),'../Exp/Square.exp',150000.)
+md = setmask(md,'all','')
+md = parameterize(md,'../Par/SquareShelf.py')
+
+# Use of SMBpddSicopolis
+md.smb  =  SMBpddSicopolis()
+# initalize pdd fields
+md.smb.initialize(md)
+md.smb.s0p = md.geometry.surface
+md.smb.s0t = md.geometry.surface
+
+# 
+md.smb.monthlytemperatures = np.empty((md.mesh.numberofvertices+1,12))
+md.smb.precipitation = np.empty((md.mesh.numberofvertices+1,12))
+temp_ma_present = -10. * np.ones((md.mesh.numberofvertices,)) - md.smb.rlaps * md.geometry.surface / 1000.
+temp_mj_present = 10. * np.ones((md.mesh.numberofvertices,)) - md.smb.rlaps * md.geometry.surface / 1000.
+precipitation = 5. * np.ones((md.mesh.numberofvertices,))
+for imonth in range(12): 
+	md.smb.monthlytemperatures[0:md.mesh.numberofvertices,imonth] = md.materials.meltingpoint + temp_ma_present + (temp_mj_present - temp_ma_present) * np.sin((imonth + 1. - 4.) * np.pi / 6.0)
+	md.smb.monthlytemperatures[md.mesh.numberofvertices,imonth] = ((imonth+1)/12.)
+	md.smb.precipitation[0:md.mesh.numberofvertices,imonth] = precipitation
+	md.smb.precipitation[md.mesh.numberofvertices,imonth] = ((imonth+1)/12.)
+
+# time steps and resolution
+md.timestepping.time_step = 1
+md.settings.output_frequency = 1
+md.timestepping.final_time = 2
+
+md.transient.issmb = 1
+md.transient.ismasstransport = 1
+md.transient.isstressbalance = 0
+md.transient.isthermal = 0
+
+md.transient.requested_outputs = ['default','TemperaturePDD']
+md.cluster = generic('name',gethostname(),'np',1) # 3 for the cluster
+md = solve(md,'Transient')
+
+#Fields and tolerances to track changes
+field_names      = ['TemperaturePDD1','SmbMassBalance1','TemperaturePDD2','SmbMassBalance2']
+field_tolerances = [1e-13,1e-13,1e-13,1e-13]
+field_values = [
+	md.results.TransientSolution[0].TemperaturePDD,
+	md.results.TransientSolution[0].SmbMassBalance,
+	md.results.TransientSolution[1].TemperaturePDD,
+	md.results.TransientSolution[1].SmbMassBalance,
+	]
+
Index: issm/trunk/test/NightlyRun/test290.m
===================================================================
--- issm/trunk/test/NightlyRun/test290.m	(revision 23389)
+++ issm/trunk/test/NightlyRun/test290.m	(revision 23394)
@@ -11,5 +11,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={5e-5,5e-5,8e-5,5e-5,1e-7};
+field_tolerances={5e-5,5e-5,8e-4,5e-4,2e-7};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: issm/trunk/test/NightlyRun/test290.py
===================================================================
--- issm/trunk/test/NightlyRun/test290.py	(revision 23389)
+++ issm/trunk/test/NightlyRun/test290.py	(revision 23394)
@@ -21,5 +21,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx', 'Vy', 'Vz', 'Vel','Pressure']
-field_tolerances=[5e-5,5e-5,8e-5,5e-5,1e-7]
+field_tolerances=[5e-5,5e-5,8e-4,5e-4,2e-7]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: issm/trunk/test/NightlyRun/test3015.m
===================================================================
--- issm/trunk/test/NightlyRun/test3015.m	(revision 23389)
+++ issm/trunk/test/NightlyRun/test3015.m	(revision 23394)
@@ -15,12 +15,23 @@
 %setup autodiff parameters
 index=1; %this is the scalar component we are checking against
-md.autodiff.independents={...
-	independent('name','md.geometry.thickness','type','vertex','nods',md.mesh.numberofvertices,'fos_forward_index',index)
+
+if IssmConfig('_HAVE_CODIPACK_')
+	md.autodiff.independents={...
+		independent('name','md.geometry.thickness','type','vertex','nods',md.mesh.numberofvertices)
+	};
+	md.autodiff.dependents={...
+		dependent('name','IceVolume','type','scalar','fos_reverse_index',index)...
+		};
+	md.autodiff.driver='fos_reverse';
+else
+	md.autodiff.independents={...
+		independent('name','md.geometry.thickness','type','vertex','nods',md.mesh.numberofvertices,'fos_forward_index',index)
 	};
 
-md.autodiff.dependents={...
-	dependent('name','IceVolume','type','scalar')...
-	};
-md.autodiff.driver='fos_forward';
+	md.autodiff.dependents={...
+		dependent('name','IceVolume','type','scalar')...
+		};
+	md.autodiff.driver='fos_forward';
+end
 
 %parameters for the step-wise derivative
@@ -70,7 +81,11 @@
 md=solve(md,'Masstransport');
 %retrieve directly
-dVdh_ad=md.results.MasstransportSolution.AutodiffJacobian;
+if IssmConfig('_HAVE_CODIPACK_')
+	dVdh_ad=md.results.MasstransportSolution.AutodiffJacobian(index);
+else
+	dVdh_ad=md.results.MasstransportSolution.AutodiffJacobian;
+end
 
-disp(sprintf('dV/dh: analytical:  %16.16g\n       using adolc:  %16.16g\n',dVdh_an,dVdh_ad));
+disp(sprintf('dV/dh: analytical:  %16.16g\n       using ad:    %16.16g\n',dVdh_an,dVdh_ad));
 
 %Fields and tolerances to track changes
Index: issm/trunk/test/NightlyRun/test3480.m
===================================================================
--- issm/trunk/test/NightlyRun/test3480.m	(revision 23389)
+++ issm/trunk/test/NightlyRun/test3480.m	(revision 23394)
@@ -18,4 +18,5 @@
 md.inversion.iscontrol=1;
 md.autodiff.isautodiff=1;
+md.autodiff.driver='fos_reverse';
 
 md.friction.coefficient(1:md.mesh.numberofvertices,1)=50;
Index: issm/trunk/test/NightlyRun/test3481.m
===================================================================
--- issm/trunk/test/NightlyRun/test3481.m	(revision 23389)
+++ issm/trunk/test/NightlyRun/test3481.m	(revision 23394)
@@ -18,4 +18,5 @@
 md.inversion.iscontrol=1;
 md.autodiff.isautodiff=1;
+md.autodiff.driver='fos_reverse';
 
 md.friction.coefficient(1:md.mesh.numberofvertices,1)=50;
Index: issm/trunk/test/NightlyRun/test413.py
===================================================================
--- issm/trunk/test/NightlyRun/test413.py	(revision 23394)
+++ issm/trunk/test/NightlyRun/test413.py	(revision 23394)
@@ -0,0 +1,66 @@
+#Test Name: SquareSheetShelfDiadSSA3dDakotaPart
+import numpy as np
+from model import *
+from socket import gethostname
+from triangle import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from solve import *
+from partitioner import *
+from importancefactors import *
+
+md = triangle(model(),'../Exp/Square.exp',150000.)
+md = setmask(md,'../Exp/SquareShelf.exp','')
+md = parameterize(md,'../Par/SquareSheetShelf.py')
+md = setflowequation(md,'SSA','all')
+md.cluster = generic('name',gethostname(),'np',3)
+
+#Dakota options
+
+#dakota version
+version = IssmConfig('_DAKOTA_VERSION_')
+version = float(version[0])
+
+#partitioning
+md.qmu.numberofpartitions = 20
+md = partitioner(md,'package','chaco','npart',md.qmu.numberofpartitions,'weighting','on')
+md.qmu.partition = md.qmu.partition-1
+
+#variables
+md.qmu.variables.rho_ice = normal_uncertain.normal_uncertain('MaterialsRhoIce',md.materials.rho_ice,0.01)
+md.qmu.variables.drag_coefficient = normal_uncertain.normal_uncertain('scaled_FrictionCoefficient',1,0.01)
+
+#responses
+md.qmu.responses.MaxVel = response_function.response_function('MaxVel',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+
+#method
+md.qmu.method = dakota_method.dakota_method('nond_l')
+
+#parameters
+md.qmu.params.direct = True
+md.qmu.params.interval_type = 'forward'
+
+if version >= 6:
+	md.qmu.params.analysis_driver = 'matlab'
+	md.qmu.params.evaluation_scheduling = 'master'
+	md.qmu.params.processors_per_evaluation = 2
+else:
+	md.qmu.params.analysis_driver = 'stressbalance'
+	md.qmu.params.evaluation_concurrency = 1
+
+
+#imperative!
+md.stressbalance.reltol = 10**-5 #tighten for qmu analyses
+md.qmu.isdakota = 1
+
+#solve
+md.verbose = verbose('000000000')	# this line is recommended
+md = solve(md,'Stressbalance','overwrite','y')
+
+#Fields and tolerances to track changes
+md.qmu.results = md.results.dakota
+md.results.dakota.importancefactors = importancefactors(md,'scaled_FrictionCoefficient','MaxVel').T
+field_names = ['importancefactors']
+field_tolerances = [1e-10]
+field_values = [md.results.dakota.importancefactors]
Index: issm/trunk/test/NightlyRun/test414.py
===================================================================
--- issm/trunk/test/NightlyRun/test414.py	(revision 23394)
+++ issm/trunk/test/NightlyRun/test414.py	(revision 23394)
@@ -0,0 +1,92 @@
+#Test Name: SquareSheetShelfDiadSSA3dDakotaMassFlux
+import numpy as np
+from os import getcwd
+from model import *
+from socket import gethostname
+from triangle import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from solve import *
+from partitioner import *
+
+md = triangle(model(),'../Exp/Square.exp',150000.)
+md = setmask(md,'../Exp/SquareShelf.exp','')
+md = parameterize(md,'../Par/SquareSheetShelf.py')
+md = setflowequation(md,'SSA','all')
+md.cluster = generic('name',gethostname(),'np',3)
+md.materials.rho_ice = 10**7 #involved in the mass flux, make it easy
+md.geometry.thickness[:] = 1 #make it easy
+md.geometry.surface = md.geometry.base+md.geometry.thickness
+
+#constrain all velocities to 1 m/yr, in the y-direction
+md.stressbalance.spcvx = np.zeros((md.mesh.numberofvertices,))
+md.stressbalance.spcvy = np.ones((md.mesh.numberofvertices,))
+md.stressbalance.spcvz = np.zeros((md.mesh.numberofvertices,))
+
+#Dakota options
+
+#dakota version
+version = IssmConfig('_DAKOTA_VERSION_')
+version = float(version[0])
+
+#partitioning
+md.qmu.numberofpartitions = 20
+md = partitioner(md,'package','chaco','npart',md.qmu.numberofpartitions,'weighting','on')
+md.qmu.partition = md.qmu.partition-1
+
+#variables
+md.qmu.variables.drag_coefficient = normal_uncertain.normal_uncertain('scaled_FrictionCoefficient',1,0.01)
+
+#responses
+md.qmu.responses.MaxVel = response_function.response_function('MaxVel',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux1 = response_function.response_function('indexed_MassFlux_1',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux2 = response_function.response_function('indexed_MassFlux_2',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux3 = response_function.response_function('indexed_MassFlux_3',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux4 = response_function.response_function('indexed_MassFlux_4',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux5 = response_function.response_function('indexed_MassFlux_5',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux6 = response_function.response_function('indexed_MassFlux_6',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux7 = response_function.response_function('indexed_MassFlux_7',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+
+#mass flux profiles
+md.qmu.mass_flux_profiles = ['../Exp/MassFlux1.exp','../Exp/MassFlux2.exp','../Exp/MassFlux3.exp','../Exp/MassFlux4.exp','../Exp/MassFlux5.exp','../Exp/MassFlux6.exp','../Exp/Square.exp']
+md.qmu.mass_flux_profile_directory = getcwd()
+
+#method
+md.qmu.method = dakota_method.dakota_method('nond_l')
+
+#parameters
+md.qmu.params.direct = True
+md.qmu.params.interval_type = 'forward'
+md.qmu.isdakota = 1
+md.stressbalance.reltol = 10**-5 #tighten for qmu analyses
+
+if version >= 6:
+	md.qmu.params.analysis_driver = 'matlab'
+	md.qmu.params.evaluation_scheduling = 'master'
+	md.qmu.params.processors_per_evaluation = 2
+else:
+	md.qmu.params.analysis_driver = 'stressbalance'
+	md.qmu.params.evaluation_concurrency = 1
+
+#solve
+md.verbose = verbose('000000000')	# this line is recommended
+md = solve(md,'Stressbalance','overwrite','y')
+md.qmu.results = md.results.dakota
+
+#Fields and tolerances to track changes
+#ok, mass flux of 3 profiles should be -3 Gt/yr -3 Gt/yr and the sum, which is -6 Gt/yr
+#we recover those mass fluxes through the mean of the response.
+#also, we recover the max velo, which should be 1m/yr. 
+#we put all that data in the moments, which we will use to test for success.
+#also, check that the stddev are 0.
+md.results.dakota.moments = []
+for i in range(8):
+	md.results.dakota.moments.append(md.results.dakota.dresp_out[i].mean)
+
+for i in range(8):
+	md.results.dakota.moments.append(md.results.dakota.dresp_out[i].stddev)
+
+field_names      = ['moments']
+field_tolerances = [1e-11]
+field_values = [md.results.dakota.moments]
Index: issm/trunk/test/NightlyRun/test417.py
===================================================================
--- issm/trunk/test/NightlyRun/test417.py	(revision 23394)
+++ issm/trunk/test/NightlyRun/test417.py	(revision 23394)
@@ -0,0 +1,106 @@
+#Test Name: SquareSheetShelfDiadSSA3dDakotaSamp
+import numpy as np
+from os import getcwd
+from model import *
+from socket import gethostname
+from triangle import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from solve import *
+from partitioner import *
+from dmeth_params_set import *
+
+md = triangle(model(),'../Exp/Square.exp',150000.)
+md = setmask(md,'../Exp/SquareShelf.exp','')
+md = parameterize(md,'../Par/SquareSheetShelf.py')
+md = setflowequation(md,'SSA','all')
+md.cluster = generic('name',gethostname(),'np',3)
+md.materials.rho_ice = 10**7 #involved in the mass flux, make it easy
+md.geometry.thickness[:] = 1 #make it easy
+md.geometry.surface = md.geometry.base+md.geometry.thickness
+
+#constrain all velocities to 1 m/yr, in the y-direction
+md.stressbalance.spcvx[:] = 0
+md.stressbalance.spcvy[:] = 1
+md.stressbalance.spcvz[:] = 0
+
+#Dakota options
+
+#dakota version
+version = IssmConfig('_DAKOTA_VERSION_')
+version = float(version[0])
+
+#partitioning
+md.qmu.numberofpartitions = 20
+md = partitioner(md,'package','chaco','npart',md.qmu.numberofpartitions,'weighting','on')
+md.qmu.partition = md.qmu.partition-1
+
+#variables
+md.qmu.variables.drag_coefficient = normal_uncertain.normal_uncertain('scaled_FrictionCoefficient',1,0.01)
+
+#responses
+md.qmu.responses.MaxVel = response_function.response_function('MaxVel',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux1 = response_function.response_function('indexed_MassFlux_1',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux2 = response_function.response_function('indexed_MassFlux_2',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux3 = response_function.response_function('indexed_MassFlux_3',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux4 = response_function.response_function('indexed_MassFlux_4',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux5 = response_function.response_function('indexed_MassFlux_5',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux6 = response_function.response_function('indexed_MassFlux_6',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.MassFlux7 = response_function.response_function('indexed_MassFlux_7',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+
+#mass flux profiles
+md.qmu.mass_flux_profiles = ['../Exp/MassFlux1.exp','../Exp/MassFlux2.exp','../Exp/MassFlux3.exp','../Exp/MassFlux4.exp','../Exp/MassFlux5.exp','../Exp/MassFlux6.exp','../Exp/Square.exp']
+md.qmu.mass_flux_profile_directory = getcwd()
+
+#method
+md.qmu.method = dakota_method.dakota_method('nond_samp')
+md.qmu.method = dmeth_params_set(md.qmu.method,'seed',1234,'samples',20,'sample_type','lhs')
+
+#parameters
+md.qmu.params.direct = True
+md.qmu.params.analysis_components = ''
+md.qmu.params.tabular_graphics_data = True;
+
+if version >= 6:
+	md.qmu.params.analysis_driver = 'matlab'
+	md.qmu.params.evaluation_scheduling = 'master'
+	md.qmu.params.processors_per_evaluation = 2
+else:
+	md.qmu.params.analysis_driver = 'stressbalance'
+	md.qmu.params.evaluation_concurrency = 1
+
+#partitioning
+md.qmu.numberofpartitions = 20
+md = partitioner(md,'package','chaco','npart',md.qmu.numberofpartitions,'weighting','on')
+md.qmu.partition = md.qmu.partition-1
+md.qmu.isdakota = 1
+
+md.stressbalance.reltol = 10**-5	#tighten for qmu analyses
+
+#solve
+md.verbose = verbose('000000000')	# this line is recommended
+
+# There may be a pair of numpy warnings in the function true_divide,
+#	this is normal and will not affect the results
+#	See src/m/qmu/dakota_out_parse.py, function "dak_tab_out" for details
+md = solve(md,'Stressbalance','overwrite','y')
+
+#Fields and tolerances to track changes
+md.qmu.results = md.results.dakota
+
+#ok, mass flux of 3 profiles should be -3 Gt/yr -3 Gt/yr and the sum, which is -6 Gt/yr
+#we recover those mass fluxes through the mean of the response.
+#also, we recover the max velo, which should be 1m/yr. 
+#we put all that data in the montecarlo field, which we will use to test for success.
+#also, check that the stddev are 0.
+md.results.dakota.montecarlo = []
+for i in range(8):
+	md.results.dakota.montecarlo.append(md.results.dakota.dresp_out[i].mean)
+
+for i in range(8):
+	md.results.dakota.montecarlo.append(md.results.dakota.dresp_out[i].stddev)
+
+field_names      = ['moments']
+field_tolerances = [1e-11]
+field_values     = [md.results.dakota.montecarlo]
Index: issm/trunk/test/NightlyRun/test418.py
===================================================================
--- issm/trunk/test/NightlyRun/test418.py	(revision 23394)
+++ issm/trunk/test/NightlyRun/test418.py	(revision 23394)
@@ -0,0 +1,43 @@
+#Test Name: SquareSheetShelfDiadSSA3dDakotaAreaAverage
+
+# this test may crash
+
+import numpy as np
+from model import *
+from socket import gethostname
+from triangle import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from solve import *
+from partitioner import *
+from AreaAverageOntoPartition import *
+
+#test partitioning, and partition averaging
+# python cannot handle resolutions greater than 30010
+md = triangle(model(),'../Exp/Square.exp',30000.)
+#print md.mesh.numberofvertices
+md = setmask(md,'../Exp/SquareShelf.exp','')
+md = parameterize(md,'../Par/SquareSheetShelf.py')
+md = setflowequation(md,'SSA','all')
+md.cluster = generic('name',gethostname(),'np',3)
+
+#partitioning
+md.qmu.numberofpartitions = 100
+
+#corrupted size vs. prev_size
+#Aborted (core dumped)
+md = partitioner(md,'package','chaco','npart',md.qmu.numberofpartitions)
+
+
+md.qmu.partition=md.qmu.partition-1
+
+vector = np.arange(1,1+md.mesh.numberofvertices,1).reshape(-1,1)
+# double check this before committing:
+#print 'before AreaAverageOntoPartition'
+vector_on_partition = AreaAverageOntoPartition(md,vector)
+vector_on_nodes = vector_on_partition[md.qmu.partition+1]
+
+field_names      = ['vector_on_nodes']
+field_tolerances = [1e-11]
+field_values     = [vector_on_nodes]
Index: issm/trunk/test/NightlyRun/test420.py
===================================================================
--- issm/trunk/test/NightlyRun/test420.py	(revision 23394)
+++ issm/trunk/test/NightlyRun/test420.py	(revision 23394)
@@ -0,0 +1,71 @@
+#Test Name: SquareSheetShelfDakotaScaledResponse
+
+import numpy as np
+from model import *
+from socket import gethostname
+from triangle import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from solve import *
+from partitioner import *
+
+md = triangle(model(),'../Exp/Square.exp',200000.)
+md = setmask(md,'../Exp/SquareShelf.exp','')
+md = parameterize(md,'../Par/SquareSheetShelf.py')
+md = setflowequation(md,'SSA','all')
+md.cluster = generic('name',gethostname(),'np',3)
+
+#partitioning
+md.qmu.numberofpartitions = 10
+md = partitioner(md,'package','chaco','npart',md.qmu.numberofpartitions)
+md.qmu.partition = md.qmu.partition-1
+md.qmu.isdakota = 1
+
+#Dakota options
+
+#dakota version
+version = IssmConfig('_DAKOTA_VERSION_')
+version = float(version[0])
+
+#variables
+md.qmu.variables.rho_ice = normal_uncertain.normal_uncertain('MaterialsRhoIce',md.materials.rho_ice,0.01)
+
+#responses
+md.qmu.responses.MaxVel = response_function.response_function('scaled_Thickness',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+
+#method
+md.qmu.method = dakota_method.dakota_method('nond_l')
+
+#parameters
+md.qmu.params.direct = True
+md.qmu.params.interval_type = 'forward'
+
+if version >= 6:
+	md.qmu.params.analysis_driver = 'matlab'
+	md.qmu.params.evaluation_scheduling = 'master'
+	md.qmu.params.processors_per_evaluation = 2
+else:
+	md.qmu.params.analysis_driver = 'stressbalance'
+	md.qmu.params.evaluation_concurrency = 1
+
+#imperative! 
+md.stressbalance.reltol = 10**-5 #tighten for qmu analysese
+
+#solve
+md.verbose = verbose('000000000')	# this line is recommended
+md = solve(md,'Stressbalance','overwrite','y')
+md.qmu.results = md.results.dakota
+
+#test on thickness
+h = np.zeros((md.qmu.numberofpartitions,))
+for i in range(md.qmu.numberofpartitions):
+	h[i] = md.qmu.results.dresp_out[i].mean
+
+#project onto grid
+thickness = h[(md.qmu.partition).flatten()]
+
+#Fields and tolerances to track changes
+field_names      = ['Thickness']
+field_tolerances = [1e-10]
+field_values     = [thickness]
Index: issm/trunk/test/NightlyRun/test421.m
===================================================================
--- issm/trunk/test/NightlyRun/test421.m	(revision 23389)
+++ issm/trunk/test/NightlyRun/test421.m	(revision 23394)
@@ -10,5 +10,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1e-06,9e-07,2e-05,2e-06,2e-06};
+field_tolerances={2e-06,9e-07,2e-05,2e-06,2e-06};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: issm/trunk/test/NightlyRun/test421.py
===================================================================
--- issm/trunk/test/NightlyRun/test421.py	(revision 23389)
+++ issm/trunk/test/NightlyRun/test421.py	(revision 23394)
@@ -20,5 +20,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[1e-06,9e-07,2e-05,2e-06,2e-06]
+field_tolerances=[2e-06,9e-07,2e-05,2e-06,2e-06]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: issm/trunk/test/NightlyRun/test444.py
===================================================================
--- issm/trunk/test/NightlyRun/test444.py	(revision 23394)
+++ issm/trunk/test/NightlyRun/test444.py	(revision 23394)
@@ -0,0 +1,127 @@
+#Test Name: SquareShelfTranForceNeg2dDakotaLocal
+import numpy as np
+from os import getcwd
+from model import *
+from socket import gethostname
+from triangle import *
+from setmask import *
+from parameterize import *
+from setflowequation import *
+from solve import *
+from SMBgemb import *
+from partitioner import *
+from dmeth_params_set import *
+from ContourToMesh import *
+from regionaloutput import *
+
+#model not consistent:  equality thickness=surface-base violated
+
+md = triangle(model(),'../Exp/Square.exp',150000.)
+md = setmask(md,'../Exp/SquareShelf.exp','')
+md = parameterize(md,'../Par/SquareSheetShelf.py')
+md.geometry.bed = md.geometry.base.copy()
+pos = np.where(md.mask.groundedice_levelset < 0)
+md.geometry.bed[pos] = md.geometry.base[pos]-10
+md.friction.coefficient = 20. * np.ones((md.mesh.numberofvertices,))
+md.friction.p = np.ones((md.mesh.numberofelements,))
+md.friction.q = np.ones((md.mesh.numberofelements,))
+md.transient.isthermal = 0
+md.transient.isgroundingline = 1
+md.groundingline.migration = 'AggressiveMigration'
+
+md.settings.output_frequency = 3
+md = setflowequation(md,'SSA','all')
+md.cluster = generic('name',oshostname(),'np',3)
+
+regionalmask = np.zeros((md.mesh.numberofvertices,))
+c_in = ContourToMesh(md.mesh.elements,md.mesh.x,md.mesh.y,'../Exp/SquareHalfRight.exp','node',1)
+regionalmask[np.where(c_in)] = 1
+md.transient.requested_outputs = ['default','GroundedArea','FloatingArea','IceVolumeAboveFloatation','GroundedArea1','FloatingArea1','TotalFloatingBmb1','TotalGroundedBmb1','TotalSmb1',
+	'IceMass1','IceVolume1','IceVolumeAboveFloatation1','IceVolumeAboveFloatation']
+md.outputdefinition.definitions.append(regionaloutput('name','GroundedArea1','outputnamestring','GroundedArea','mask',regionalmask,
+	'definitionstring','Outputdefinition1'))
+md.outputdefinition.definitions.append(regionaloutput('name','FloatingArea1','outputnamestring','FloatingArea','mask',regionalmask,
+	'definitionstring','Outputdefinition2'))
+md.outputdefinition.definitions.append(regionaloutput('name','TotalFloatingBmb1','outputnamestring','TotalFloatingBmb','mask',regionalmask,
+	'definitionstring','Outputdefinition3'))
+md.outputdefinition.definitions.append(regionaloutput('name','TotalGroundedBmb1','outputnamestring','TotalGroundedBmb','mask',regionalmask,
+	'definitionstring','Outputdefinition4'))
+md.outputdefinition.definitions.append(regionaloutput('name','IceMass1','outputnamestring','IceMass','mask',regionalmask,
+	'definitionstring','Outputdefinition5'))
+md.outputdefinition.definitions.append(regionaloutput('name','IceVolume1','outputnamestring','IceVolume','mask',regionalmask,
+	'definitionstring','Outputdefinition6'))
+md.outputdefinition.definitions.append(regionaloutput('name','IceVolumeAboveFloatation1','outputnamestring','IceVolumeAboveFloatation','mask',regionalmask,
+	'definitionstring','Outputdefinition7'))
+md.outputdefinition.definitions.append(regionaloutput('name','TotalSmb1','outputnamestring','TotalSmb','mask',regionalmask,
+	'definitionstring','Outputdefinition8'))
+md.outputdefinition.definitions.append(regionaloutput('name','TotalSmb2','outputnamestring','TotalSmb','mask',regionalmask,
+	 'definitionstring','Outputdefinition9'))
+
+md.extrude(3,1.)
+md.collapse()
+
+#Dakota options
+
+#dakota version
+version = IssmConfig('_DAKOTA_VERSION_')
+version = float(version[0])
+
+#variables
+md.qmu.variables.drag_coefficient = normal_uncertain.normal_uncertain('scaled_BasalforcingsFloatingiceMeltingRate',1,0.1)
+
+#responses
+md.qmu.responses.IceMass1 = response_function.response_function('Outputdefinition5',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.IceVolume1 = response_function.response_function('Outputdefinition6',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.IceVolumeAboveFloatation1 = response_function.response_function('Outputdefinition7',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.IceVolumeAboveFloatation = response_function.response_function('IceVolumeAboveFloatation',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.GroundedArea1 = response_function.response_function('Outputdefinition1',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.FloatingArea1 = response_function.response_function('Outputdefinition2',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.TotalFloatingBmb1 = response_function.response_function('Outputdefinition3',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.TotalGroundedBmb1 = response_function.response_function('Outputdefinition4',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.TotalSmb1 = response_function.response_function('Outputdefinition8',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.TotalSmb2 = response_function.response_function('Outputdefinition9',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+md.qmu.responses.FloatingArea = response_function.response_function('FloatingArea',[],[0.0001,0.001,0.01,0.25,0.5,0.75,0.99,0.999,0.9999])
+
+#method
+md.qmu.method = dakota_method.dakota_method('nond_samp')
+md.qmu.method = dmeth_params_set(md.qmu.method,'seed',1234,'samples',20,'sample_type','random')
+
+#parameters
+md.qmu.params.direct = True
+md.qmu.params.analysis_components = ''
+md.qmu.params.tabular_graphics_data = True
+
+if version >= 6:
+	md.qmu.params.analysis_driver = 'matlab'
+	md.qmu.params.evaluation_scheduling = 'master'
+	md.qmu.params.processors_per_evaluation = 2
+else:
+	md.qmu.params.analysis_driver = 'stressbalance'
+	md.qmu.params.evaluation_concurrency = 1
+
+#partitioning
+md.qmu.numberofpartitions = 10
+md = partitioner(md,'package','chaco','npart',md.qmu.numberofpartitions,'weighting','on')
+md.qmu.partition = md.qmu.partition-1
+md.qmu.isdakota = 1
+
+md.stressbalance.reltol = 10**-5 #tighten for qmu analyses
+
+#solve
+md.verbose = verbose('000000000')	# this line is recommended
+md = solve(md,'Transient','overwrite','y')
+
+#Fields and tolerances to track changes
+md.qmu.results = md.results.dakota
+
+#we put all the mean and stdev data in the montecarlo field, which we will use to test for success.
+md.results.dakota.montecarlo = []
+for i in range(11):
+	md.results.dakota.montecarlo.append(md.results.dakota.dresp_out[i].mean)
+
+for i in range(11):
+	md.results.dakota.montecarlo.append(md.results.dakota.dresp_out[i].stddev)
+
+field_names      = ['montecarlo']
+field_tolerances = [1e-11]
+field_values = [md.results.dakota.montecarlo]
Index: issm/trunk/test/NightlyRun/test455.m
===================================================================
--- issm/trunk/test/NightlyRun/test455.m	(revision 23389)
+++ issm/trunk/test/NightlyRun/test455.m	(revision 23394)
@@ -14,5 +14,5 @@
 	md=solve(md,'Stressbalance');
 	field_names     ={field_names{:},['Vx' i{1}],['Vy' i{1}],['Vz' i{1}],['Vel' i{1}],['Pressure' i{1}]};
-	field_tolerances={field_tolerances{:},6e-08,6e-08,6e-08,6e-08,3e-13};
+	field_tolerances={field_tolerances{:},7e-08,6e-08,6e-08,6e-08,3e-13};
 	field_values={field_values{:},...
 	(md.results.StressbalanceSolution.Vx),...
Index: issm/trunk/test/NightlyRun/test455.py
===================================================================
--- issm/trunk/test/NightlyRun/test455.py	(revision 23389)
+++ issm/trunk/test/NightlyRun/test455.py	(revision 23394)
@@ -24,5 +24,5 @@
 	md=solve(md,'Stressbalance')
 	field_names     =field_names+['Vx'+i,'Vy'+i,'Vz'+i,'Vel'+i,'Pressure'+i]
-	field_tolerances=field_tolerances+[6e-08,6e-08,6e-08,6e-08,3e-13]
+	field_tolerances=field_tolerances+[7e-08,6e-08,6e-08,6e-08,3e-13]
 	field_values=field_values+[\
 			md.results.StressbalanceSolution.Vx,\
Index: issm/trunk/test/NightlyRun/test701.m
===================================================================
--- issm/trunk/test/NightlyRun/test701.m	(revision 23389)
+++ issm/trunk/test/NightlyRun/test701.m	(revision 23394)
@@ -35,4 +35,5 @@
 md.stressbalance.spcvx(find(vertexflags(md.mesh,4)))=0;
 md.stressbalance.spcvy(find(vertexflags(md.mesh,4)))=0;
+md.basalforcings.floatingice_melting_rate=zeros(md.mesh.numberofvertices,1);
 
 %Misc
Index: issm/trunk/test/NightlyRun/test701.py
===================================================================
--- issm/trunk/test/NightlyRun/test701.py	(revision 23389)
+++ issm/trunk/test/NightlyRun/test701.py	(revision 23394)
@@ -42,4 +42,5 @@
 md.stressbalance.spcvx[np.where(md.mesh.vertexflags(4))] = 0.
 md.stressbalance.spcvy[np.where(md.mesh.vertexflags(4))] = 0.
+md.basalforcings.floatingice_melting_rate=np.zeros((md.mesh.numberofvertices,))
 
 #Misc
Index: issm/trunk/test/NightlyRun/test702.m
===================================================================
--- issm/trunk/test/NightlyRun/test702.m	(revision 23389)
+++ issm/trunk/test/NightlyRun/test702.m	(revision 23394)
@@ -34,4 +34,5 @@
 md.stressbalance.spcvx(find(vertexflags(md.mesh,4)))=800;
 md.stressbalance.spcvy(find(vertexflags(md.mesh,4)))=0;
+md.basalforcings.floatingice_melting_rate=zeros(md.mesh.numberofvertices,1);
 
 %Misc
Index: issm/trunk/test/NightlyRun/test702.py
===================================================================
--- issm/trunk/test/NightlyRun/test702.py	(revision 23394)
+++ issm/trunk/test/NightlyRun/test702.py	(revision 23394)
@@ -0,0 +1,85 @@
+#Test Name: FlowbandFSsheetshelf
+import numpy as np
+#from scipy.interpolate import interp1d
+from model import  * 
+from setflowequation import  * 
+from solve import  *
+from NowickiProfile import *
+from bamgflowband import *
+from paterson import *
+
+#mesh parameters
+x = np.arange(-5,5.5,.5).T
+[b,h,sea] = NowickiProfile(x)
+x = x * 10**3
+h = h * 10**3
+b = (b-sea) * 10**3
+
+#mesh domain
+md = bamgflowband(model(),x,b+h,b,'hmax',150.)
+
+#parameterize
+md.geometry.surface = np.interp(md.mesh.x,x,b+h)
+md.geometry.base = np.interp(md.mesh.x,x,b)
+md.geometry.thickness = md.geometry.surface - md.geometry.base
+
+#mask
+md.mask.ice_levelset = -np.ones((md.mesh.numberofvertices,))
+md.mask.ice_levelset[np.where(md.mesh.vertexflags(2))] = 0
+md.mask.groundedice_levelset = -0.5*np.ones((md.mesh.numberofvertices))
+md.mask.groundedice_levelset[np.where(md.mesh.x<0)]=0.5
+
+#materials
+md.initialization.temperature = (273. - 20.) * np.ones((md.mesh.numberofvertices,))
+md.materials.rheology_B = paterson(md.initialization.temperature)
+md.materials.rheology_n = 3 * np.ones((md.mesh.numberofelements,))
+
+#damage
+md.damage.D = np.zeros((md.mesh.numberofvertices,))
+md.damage.spcdamage = float('NaN') * np.ones((md.mesh.numberofvertices,))
+
+#friciton
+md.friction.coefficient = np.zeros((md.mesh.numberofvertices,))
+md.friction.coefficient[np.where(md.mesh.vertexflags(1))] = 20
+md.friction.p = np.ones((md.mesh.numberofelements,))
+md.friction.q = np.ones((md.mesh.numberofelements,))
+
+#boundary conditions
+md.stressbalance.spcvx = float('NaN') * np.ones((md.mesh.numberofvertices,))
+md.stressbalance.spcvy = float('NaN') * np.ones((md.mesh.numberofvertices,))
+md.stressbalance.spcvz = float('NaN') * np.ones((md.mesh.numberofvertices,))
+md.stressbalance.referential = float('NaN') * np.ones((md.mesh.numberofvertices,6))
+md.stressbalance.loadingforce = np.zeros((md.mesh.numberofvertices,3))
+md.stressbalance.spcvx[np.where(md.mesh.vertexflags(4))] = 800.
+md.stressbalance.spcvy[np.where(md.mesh.vertexflags(4))] = 0.
+md.basalforcings.floatingice_melting_rate=np.zeros((md.mesh.numberofvertices,))
+
+#misc
+md = setflowequation(md,'FS','all')
+md.stressbalance.abstol = float('NaN')
+md.stressbalance.FSreconditioning = 1
+md.stressbalance.maxiter = 20
+md.flowequation.augmented_lagrangian_r = 10000.
+md.flowequation.augmented_lagrangian_rhop = 10000.
+md.initialization.pressure = md.constants.g * md.materials.rho_ice * (md.geometry.surface - md.mesh.y)
+md.miscellaneous.name = 'test702'
+md.groundingline.migration = 'None'
+md.cluster = generic('np',2)
+
+#Fields and tolerances to track changes
+field_names = []
+field_tolerances = []
+field_values = []
+for i in ['MINI','MINIcondensed','TaylorHood','XTaylorHood','LATaylorHood']:
+	print ' '
+	print '======Testing ' +i+ ' Full-Stokes Finite element====='
+	md.flowequation.fe_FS = i
+	md = solve(md,'Stressbalance')
+	field_names.extend(['Vx'+i,'Vy'+i,'Vel'+i,'Pressure'+i])
+	field_tolerances.extend([8e-5,8e-5,8e-5,1e-08])
+	field_values.extend([
+		md.results.StressbalanceSolution.Vx,
+		md.results.StressbalanceSolution.Vy,
+		md.results.StressbalanceSolution.Vel,
+		md.results.StressbalanceSolution.Pressure
+		])
