Index: /issm/trunk-jpl/src/c/cores/ad_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/cores/ad_core.cpp	(revision 23249)
+++ /issm/trunk-jpl/src/c/cores/ad_core.cpp	(revision 23250)
@@ -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-jpl/src/c/cores/adgradient_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/cores/adgradient_core.cpp	(revision 23249)
+++ /issm/trunk-jpl/src/c/cores/adgradient_core.cpp	(revision 23250)
@@ -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-jpl/src/c/cores/controladm1qn3_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/cores/controladm1qn3_core.cpp	(revision 23249)
+++ /issm/trunk-jpl/src/c/cores/controladm1qn3_core.cpp	(revision 23250)
@@ -168,4 +168,6 @@
 	/*Print tape statistics so that user can kill this run if something is off already:*/
 	if(VerboseAutodiff()){ /*{{{*/
+
+		#ifdef _HAVE_ADOLC_
 		size_t  tape_stats[15];
 		tapestats(my_rank,tape_stats); //reading of tape statistics
@@ -208,4 +210,14 @@
 		}
 		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
 	} /*}}}*/
 
