Index: ../trunk-jpl/src/c/analyses/AdjointHorizAnalysis.cpp
===================================================================
--- ../trunk-jpl/src/c/analyses/AdjointHorizAnalysis.cpp	(revision 18770)
+++ ../trunk-jpl/src/c/analyses/AdjointHorizAnalysis.cpp	(revision 18771)
@@ -41,6 +41,8 @@
 	switch(approximation){
 		case SSAApproximationEnum: 
 			return CreateKMatrixSSA(element);
+		case L1L2ApproximationEnum: 
+			return CreateKMatrixL1L2(element);
 		case HOApproximationEnum: 
 			return CreateKMatrixHO(element);
 		case FSApproximationEnum: 
@@ -138,6 +140,23 @@
 	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
 	return Ke;
 }/*}}}*/
+ElementMatrix* AdjointHorizAnalysis::CreateKMatrixL1L2(Element* element){/*{{{*/
+
+	/*Intermediaries*/
+	bool incomplete_adjoint;
+
+	/*Initialize Jacobian with regular L1L2 (first part of the Gateau derivative)*/
+	StressbalanceAnalysis* analysis = new StressbalanceAnalysis();
+	ElementMatrix* Ke=analysis->CreateKMatrix(element);
+	delete analysis;
+
+	/*return*/
+	element->FindParam(&incomplete_adjoint,InversionIncompleteAdjointEnum);
+	if(!incomplete_adjoint){
+		_error_("Exact adjoint not supported yet for L1L2 model");
+	}
+	return Ke;
+}/*}}}*/
 ElementMatrix* AdjointHorizAnalysis::CreateKMatrixHO(Element* element){/*{{{*/
 
 	/*Intermediaries */
@@ -299,6 +318,8 @@
 	switch(approximation){
 		case SSAApproximationEnum: 
 			return CreatePVectorSSA(element);
+		case L1L2ApproximationEnum: 
+			return CreatePVectorL1L2(element);
 		case HOApproximationEnum: 
 			return CreatePVectorHO(element);
 		case FSApproximationEnum: 
@@ -896,6 +917,11 @@
 	delete gauss;
 	return pe;
 }/*}}}*/
+ElementVector* AdjointHorizAnalysis::CreatePVectorL1L2(Element* element){/*{{{*/
+
+	/*Same as SSA*/
+	return this->CreatePVectorSSA(element);
+}/*}}}*/
 void AdjointHorizAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
 	   _error_("not implemented yet");
 }/*}}}*/
@@ -945,6 +971,7 @@
 		case FrictionCoefficientEnum:
 			switch(approximation){
 				case SSAApproximationEnum: GradientJDragSSA(element,gradient,control_index); break;
+				case L1L2ApproximationEnum:GradientJDragL1L2(element,gradient,control_index); break;
 				case HOApproximationEnum:  GradientJDragHO( element,gradient,control_index); break;
 				case FSApproximationEnum:  GradientJDragFS( element,gradient,control_index); break;
 				case NoneApproximationEnum: /*Gradient is 0*/                    break;
@@ -954,6 +981,7 @@
 		case MaterialsRheologyBbarEnum:
 			switch(approximation){
 				case SSAApproximationEnum: GradientJBbarSSA(element,gradient,control_index); break;
+				case L1L2ApproximationEnum:GradientJBbarL1L2(element,gradient,control_index); break;
 				case HOApproximationEnum:  GradientJBbarHO( element,gradient,control_index); break;
 				case FSApproximationEnum:  GradientJBbarFS( element,gradient,control_index); break;
 				case NoneApproximationEnum: /*Gradient is 0*/                    break;
@@ -1222,6 +1250,11 @@
 	delete friction;
 	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
 }/*}}}*/
+void AdjointHorizAnalysis::GradientJDragL1L2(Element* element,Vector<IssmDouble>* gradient,int control_index){/*{{{*/
+
+	/*Same as SSA*/
+	return this->GradientJDragSSA(element,gradient,control_index);
+}/*}}}*/
 void AdjointHorizAnalysis::GradientJDragHO(Element* element,Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*return if floating or not on bed (gradient is 0)*/
@@ -1445,6 +1478,11 @@
 	delete gauss;
 	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
 }/*}}}*/
+void AdjointHorizAnalysis::GradientJBbarL1L2(Element* element,Vector<IssmDouble>* gradient,int control_index){/*{{{*/
+
+	   /*Same as SSA*/
+	   return this->GradientJBbarSSA(element,gradient,control_index);
+}/*}}}*/
 void AdjointHorizAnalysis::GradientJBbarHO(Element* element,Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*WARNING: We use SSA as an estimate for now*/
Index: ../trunk-jpl/src/c/analyses/AdjointHorizAnalysis.h
===================================================================
--- ../trunk-jpl/src/c/analyses/AdjointHorizAnalysis.h	(revision 18770)
+++ ../trunk-jpl/src/c/analyses/AdjointHorizAnalysis.h	(revision 18771)
@@ -25,10 +25,12 @@
 		ElementMatrix* CreateJacobianMatrix(Element* element);
 		ElementMatrix* CreateKMatrix(Element* element);
 		ElementMatrix* CreateKMatrixSSA(Element* element);
+		ElementMatrix* CreateKMatrixL1L2(Element* element);
 		ElementMatrix* CreateKMatrixHO(Element* element);
 		ElementMatrix* CreateKMatrixFS(Element* element);
 		ElementVector* CreatePVector(Element* element);
 		ElementVector* CreatePVectorSSA(Element* element);
+		ElementVector* CreatePVectorL1L2(Element* element);
 		ElementVector* CreatePVectorHO(Element* element);
 		ElementVector* CreatePVectorFS(Element* element);
 		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
@@ -36,9 +38,11 @@
 		void GradientJDragGradient(Element* element,Vector<IssmDouble>* gradient,int control_index);
 		void GradientJBGradient(Element* element,Vector<IssmDouble>* gradient,int control_index);
 		void GradientJDragSSA(Element* element,Vector<IssmDouble>* gradient,int control_index);
+		void GradientJDragL1L2(Element* element,Vector<IssmDouble>* gradient,int control_index);
 		void GradientJDragHO(Element* element,Vector<IssmDouble>* gradient,int control_index);
 		void GradientJDragFS(Element* element,Vector<IssmDouble>* gradient,int control_index);
 		void GradientJBbarSSA(Element* element,Vector<IssmDouble>* gradient,int control_index);
+		void GradientJBbarL1L2(Element* element,Vector<IssmDouble>* gradient,int control_index);
 		void GradientJBbarHO(Element* element,Vector<IssmDouble>* gradient,int control_index);
 		void GradientJBbarFS(Element* element,Vector<IssmDouble>* gradient,int control_index);
 		void GradientJDSSA(Element* element,Vector<IssmDouble>* gradient,int control_index);
Index: ../trunk-jpl/src/m/classes/inversion.py
===================================================================
--- ../trunk-jpl/src/m/classes/inversion.py	(revision 18770)
+++ ../trunk-jpl/src/m/classes/inversion.py	(revision 18771)
@@ -130,7 +130,7 @@
 
 		#Only SSA, HO and FS are supported right now
 		if solution==StressbalanceSolutionEnum():
-			if not (md.flowequation.isSSA or md.flowequation.isHO or md.flowequation.isFS):
+			if not (md.flowequation.isSSA or md.flowequation.isHO or md.flowequation.isFS or md.flowequation.isL1L2):
 				md.checkmessage("'inversion can only be performed for SSA, HO or FS ice flow models");
 
 		if solution==BalancethicknessSolutionEnum():
Index: ../trunk-jpl/src/m/classes/inversion.m
===================================================================
--- ../trunk-jpl/src/m/classes/inversion.m	(revision 18770)
+++ ../trunk-jpl/src/m/classes/inversion.m	(revision 18771)
@@ -145,7 +145,7 @@
 
 			%Only SSA, HO and FS are supported right now
 			if solution==StressbalanceSolutionEnum()
-				if ~(md.flowequation.isSSA || md.flowequation.isHO || md.flowequation.isFS),
+				if ~(md.flowequation.isSSA || md.flowequation.isHO || md.flowequation.isFS || md.flowequation.isL1L2),
 					md = checkmessage(md,['inversion can only be performed for SSA, HO or FS ice flow models']);
 				end
 			end
