diff --git a/Solver/TESTCASES/Stommel.lua b/Solver/TESTCASES/Stommel.lua
index 741048dbf76e8db8b9ca8ac02a1364b658de95af..2d6a259b6002398b8ffad20f93d6fab96a53c817 100644
--- a/Solver/TESTCASES/Stommel.lua
+++ b/Solver/TESTCASES/Stommel.lua
@@ -2,16 +2,43 @@ model = GModel()
 model:load ('stommel_square.msh')
 order=1
 dimension = 2
+
+CFunctions =[[
+void wind (fullMatrix<double> &sol, fullMatrix<double> &xyz) {
+  for (size_t i = 0; i< sol.size1(); i++) {
+    sol.set(i,0,sin(xyz(i,1)/1e6)/1e6);
+    sol.set(i,1,0);
+  }
+}
+void coriolis (fullMatrix<double> &sol, fullMatrix<double> &xyz) {
+  for (size_t i = 0; i< sol.size1(); i++) {
+    sol.set(i,0,1e-4+2e-11*xyz(i,1));
+  }
+}
+]]
+
+cfile = io.popen("g++ -O3 -pipe -m32 -shared -o tmp.dylib -I ../../Numeric -I../../Common -I../../build/Common -x c++ - ","w");
+cfile:write("#include\"fullMatrix.h\"\nextern \"C\" {")
+cfile:write(CFunctions)
+cfile:write("}")
+cfile:close()
+
+
 claw = dgConservationLawShallowWater2d()
 claw:addBoundaryCondition('Wall',claw:newBoundaryWall())
+zero = functionConstant({0}):getName();
+claw:setCoriolisFactor(functionC("tmp.dylib","coriolis",1,{"XYZ"}):getName())
+claw:setQuadraticDissipation(zero)
+claw:setLinearDissipation(functionConstant({1e-6}):getName())
+claw:setSource(functionC("tmp.dylib","wind",2,{"XYZ"}):getName())
+claw:setBathymetry(functionConstant({1000}):getName())
 groups = dgGroupCollection(model, dimension, order)
--- groups:split...
 groups:buildGroupsOfInterfaces()
 solution = dgDofContainer(groups, claw:getNbFields())
 solution:exportMsh('output/init')
 rk=dgRungeKutta()
 
-for i=1,100000 do
+for i=1,600 do
   norm = rk:iterate33(claw,150*(3/(2.*order+1)/2),solution)
   if ( i%100 ==0 ) then
     print ('iter ', i, norm)
diff --git a/Solver/dgConservationLawShallowWater2d.cpp b/Solver/dgConservationLawShallowWater2d.cpp
index 6f742b4a7575a6980faae355a122c70982839fb5..f6cd1d3476373c5188598b495c37470af94f7b8a 100644
--- a/Solver/dgConservationLawShallowWater2d.cpp
+++ b/Solver/dgConservationLawShallowWater2d.cpp
@@ -1,19 +1,42 @@
 #include "dgConservationLawShallowWater2d.h"
 #include "function.h"
 static double g = 9.81;
-static double h = 1000.;
-static double linearDissipation = 2e-7;
+
+class dgConservationLawShallowWater2d : public dgConservationLaw {
+  class advection;
+  class source;
+  class riemann;
+  class boundaryWall;
+  std::string _linearDissipation, _quadraticDissipation, _source, _coriolisFactor, _bathymetry;
+  public:
+  dataCacheDouble *newConvectiveFlux( dataCacheMap &cacheMap) const;
+  dataCacheDouble *newRiemannSolver( dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight) const;
+  dataCacheDouble *newDiffusiveFlux( dataCacheMap &cacheMap) const;
+  dataCacheDouble *newSourceTerm (dataCacheMap &cacheMap) const;
+  inline void setCoriolisFactor(std::string coriolisFactor){_coriolisFactor = coriolisFactor;}
+  inline void setLinearDissipation(std::string linearDissipation){_linearDissipation = linearDissipation;}
+  inline void setQuadraticDissipation(std::string quadraticDissipation){_quadraticDissipation = quadraticDissipation;}
+  inline void setSource(std::string source){_source = source;}
+  inline void setBathymetry(std::string bathymetry) {_bathymetry = bathymetry;}
+  dgConservationLawShallowWater2d() 
+  {
+    _nbf = 3; // eta u v
+  }
+  dgBoundaryCondition *newBoundaryWall();
+};
 
 class dgConservationLawShallowWater2d::advection: public dataCacheDouble {
-  dataCacheDouble &sol;
+  dataCacheDouble &sol, &_bathymetry;
   public:
-  advection(dataCacheMap &cacheMap):
+  advection(dataCacheMap &cacheMap, std::string bathymetry):
     dataCacheDouble(cacheMap,1,9),
-    sol(cacheMap.get("Solution",this))
+    sol(cacheMap.get("Solution",this)),
+    _bathymetry(cacheMap.get(bathymetry,this))
   {};
   void _eval () { 
     int nQP = _value.size1();
     for(int i=0; i< nQP; i++) {
+      double h = _bathymetry(i,0);
       double eta = sol(i,0);
       double u = sol(i,1);
       double v = sol(i,2);
@@ -35,43 +58,53 @@ class dgConservationLawShallowWater2d::advection: public dataCacheDouble {
 
 class dgConservationLawShallowWater2d::source: public dataCacheDouble {
   dataCacheDouble &xyz, &solution,&solutionGradient;
+  dataCacheDouble &_coriolisFactor, &_source, &_linearDissipation, &_quadraticDissipation;
   public :
-  source(dataCacheMap &cacheMap) : 
+  source(dataCacheMap &cacheMap, std::string linearDissipation, std::string quadraticDissipation, std::string coriolisFactor, std::string source) : 
     dataCacheDouble(cacheMap,1,3),
     xyz(cacheMap.get("XYZ",this)),
+    _coriolisFactor(cacheMap.get(coriolisFactor,this)),
+    _source(cacheMap.get(source,this)),
+    _linearDissipation(cacheMap.get(linearDissipation,this)),
+    _quadraticDissipation(cacheMap.get(quadraticDissipation,this)),
     solution(cacheMap.get("Solution",this)),
     solutionGradient(cacheMap.get("SolutionGradient",this))
-  {}
+  {
+  }
   void _eval () {
     int nQP =_value.size1();
     for (int i=0; i<nQP; i++) {
       double eta = solution(i,0);
       double u = solution(i,1);
       double v = solution(i,2);
+      double normu = hypot(u,v);
       double dudx = solutionGradient(i*3,1);
       double dvdx = solutionGradient(i*3,2);
       double dudy = solutionGradient(i*3+1,1);
       double dvdy = solutionGradient(i*3+1,2);
-      double wind = 0.1*sin(xyz(i,1)/1e6*M_PI)/1000/h;
-      double f = 1e-4+xyz(i,1)*2e-11;
+      //double f = _coriolisFactor();
+      //double wind = 0.1*sin(xyz(i,1)/1e6*M_PI)/1000/h;
+      //1e-4+xyz(i,1)*2e-11;
       _value (i,0) = 0;
-      _value (i,1) = f*v + - linearDissipation*u + wind + u*(dudx+dvdy);
-      _value (i,2) = -f*u - linearDissipation*v         + v*(dudx+dvdy);
+      _value (i,1) = _coriolisFactor(i,0)*v  - (_linearDissipation(i,0)+_quadraticDissipation(i,0)*normu)*u + _source(i,0) + u*(dudx+dvdy);
+      _value (i,2) = -_coriolisFactor(i,0)*u - (_linearDissipation(i,0)+_quadraticDissipation(i,0)*normu)*v + _source(i,1) + v*(dudx+dvdy);
     }
   }
 };
 class dgConservationLawShallowWater2d::riemann:public dataCacheDouble {
-  dataCacheDouble &normals, &solL, &solR;
+  dataCacheDouble &normals, &solL, &solR, &_bathymetry;
   public:
-  riemann(dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight):
+  riemann(dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight, std::string bathymetry):
     dataCacheDouble(cacheMapLeft,1,6),
     normals(cacheMapLeft.get("Normals", this)),
     solL(cacheMapLeft.get("Solution", this)),
-    solR(cacheMapRight.get("Solution", this))
+    solR(cacheMapRight.get("Solution", this)),
+    _bathymetry(cacheMapLeft.get(bathymetry, this))
   {};
   void _eval () { 
     int nQP = solL().size1();
     for(int i=0; i< nQP; i++) {
+      double h = _bathymetry(i,0);
       double nx = normals(0,i);
       double ny = normals(1,i);
       double HR = solR(i,0) + h, HL = solL(i,0) + h;
@@ -157,16 +190,16 @@ class dgConservationLawShallowWater2d::boundaryWall : public dgBoundaryCondition
 };
 
 dataCacheDouble *dgConservationLawShallowWater2d::newConvectiveFlux( dataCacheMap &cacheMap) const {
-  return new advection(cacheMap);
+  return new advection(cacheMap, _bathymetry);
 }
 dataCacheDouble *dgConservationLawShallowWater2d::newRiemannSolver( dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight) const {
-  return new riemann(cacheMapLeft, cacheMapRight);
+  return new riemann(cacheMapLeft, cacheMapRight, _bathymetry);
 }
 dataCacheDouble *dgConservationLawShallowWater2d::newDiffusiveFlux( dataCacheMap &cacheMap) const {
   return 0;
 }
 dataCacheDouble *dgConservationLawShallowWater2d::newSourceTerm (dataCacheMap &cacheMap) const {
-  return new source(cacheMap);
+  return new source(cacheMap, _linearDissipation, _quadraticDissipation, _coriolisFactor, _source);
 }
 
 dgBoundaryCondition *dgConservationLawShallowWater2d::newBoundaryWall(){
@@ -183,4 +216,19 @@ void dgConservationLawShallowWater2dRegisterBindings (binding *b){
   cm = cb->setConstructor<dgConservationLawShallowWater2d>();
   cm->setDescription("A new shallow water conservation law.");
   cb->setParentClass<dgConservationLaw>();
+  cm = cb->addMethod("setCoriolisFactor", &dgConservationLawShallowWater2d::setCoriolisFactor);
+  cm->setDescription("set the function to evaluate the coriolis factor du/dt = -f v ; dv/dt = f u");
+  cm->setArgNames("f",NULL);
+  cm = cb->addMethod("setLinearDissipation", &dgConservationLawShallowWater2d::setLinearDissipation);
+  cm->setDescription("set the function to evaluate the linear dissipation du/dt = -gamma u; dv/dt = -gamma v");
+  cm->setArgNames("gamma",NULL);
+  cm = cb->addMethod("setQuadraticDissipation", &dgConservationLawShallowWater2d::setQuadraticDissipation);
+  cm->setDescription("set the function to evaluate the quadratic dissipation du/dt = -c_d u||u||; dv/dt = -c_d v");
+  cm->setArgNames("gamma",NULL);
+  cm = cb->addMethod("setSource", &dgConservationLawShallowWater2d::setSource);
+  cm->setDescription("set the function to evaluate the source term du/dt = s(0); dv/dt = s(1)");
+  cm->setArgNames("s",NULL);
+  cm = cb->addMethod("setBathymetry", &dgConservationLawShallowWater2d::setBathymetry);
+  cm->setDescription("set the function to evaluate the bathymetry h (H = h+eta)");
+  cm->setArgNames("h",NULL);
 }
diff --git a/Solver/dgConservationLawShallowWater2d.h b/Solver/dgConservationLawShallowWater2d.h
index 404944542df9a5badadec703b13603b5e2deba7c..f6ac2b31d5ee253aeb6fc860241c245c704daa8a 100644
--- a/Solver/dgConservationLawShallowWater2d.h
+++ b/Solver/dgConservationLawShallowWater2d.h
@@ -2,24 +2,7 @@
 #define _DG_CONSERVATION_LAW_SHALLOW_WATER_2D_
 #include "dgConservationLaw.h"
 
-class dataCacheMap;
 class binding;
 
-class dgConservationLawShallowWater2d : public dgConservationLaw {
-  class advection;
-  class source;
-  class riemann;
-  class boundaryWall;
-  public:
-  dataCacheDouble *newConvectiveFlux( dataCacheMap &cacheMap) const;
-  dataCacheDouble *newRiemannSolver( dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight) const;
-  dataCacheDouble *newDiffusiveFlux( dataCacheMap &cacheMap) const;
-  dataCacheDouble *newSourceTerm (dataCacheMap &cacheMap) const;
-  dgConservationLawShallowWater2d() 
-  {
-    _nbf = 3; // eta u v
-  }
-  dgBoundaryCondition *newBoundaryWall();
-};
 void dgConservationLawShallowWater2dRegisterBindings(binding *b);
 #endif