diff --git a/Common/LuaBindings.cpp b/Common/LuaBindings.cpp
index 6a62a8e1f8d65b4f7eac758862042f52dfe8eed2..e20a7f8f37b077284343662d7716198f890b2d16 100644
--- a/Common/LuaBindings.cpp
+++ b/Common/LuaBindings.cpp
@@ -40,6 +40,10 @@
 #include "linearSystemCSR.h"
 #endif
 
+#if defined(HAVE_POST)
+#include "PView.h"
+#endif
+
 extern "C" {
 #include "lua.h"
 #include "lualib.h"
@@ -412,6 +416,9 @@ binding::binding()
   linearSystemCSRGmm<double>::registerBindings(this);
   elasticitySolverRegisterBindings(this); 
 #endif
+#if defined(HAVE_POST)
+  PView::registerBindings(this);
+#endif
 }
 
 binding *binding::_instance=NULL;
diff --git a/Common/LuaBindings.h b/Common/LuaBindings.h
index 86b5bba273bafe905b3121f0ffc922ecab5c6a75..b0759438f3e2e835a8c090d92e7b821ec5a269aa 100644
--- a/Common/LuaBindings.h
+++ b/Common/LuaBindings.h
@@ -17,6 +17,7 @@
 #include "GmshConfig.h"
 #include "GmshMessage.h"
 #include "Bindings.h"
+#include "SVector3.h"
 
 #if defined(HAVE_LUA)
 
@@ -108,6 +109,13 @@ class luaStack<int>{
   static std::string getName(){ return "int"; }
 };
 
+template<>
+class luaStack<bool>{
+ public:
+  static int get(lua_State *L, int ia){ return lua_toboolean(L, ia); }
+  static void push(lua_State *L, bool i){ lua_pushboolean(L, i); }
+  static std::string getName(){ return "bool"; }
+};
 template<>
 class luaStack<unsigned int>{
  public:
@@ -178,6 +186,7 @@ class luaStack<std::list<lType > >{
   }
 };
 
+
 template<class type>
 class luaStack<std::vector<type> &>{
  public:
@@ -245,6 +254,36 @@ class luaStack<double>{
   static std::string getName(){ return "double"; }
 };
 
+template <>
+class luaStack<SVector3>{
+ public:
+  static SVector3 get(lua_State *L, int ia)
+  {
+    double v[3];
+    size_t size = lua_objlen(L, ia);
+    if (size!=3)
+      luaL_typerror(L, ia, "SVector3");
+    for(size_t i = 0; i< size; i++){
+      lua_rawgeti(L, ia, i + 1);
+      v[i] = luaStack<double>::get(L, -1);
+      lua_pop(L, 1);
+    }
+    return SVector3(v[0],v[1],v[2]);
+  }
+  static void push(lua_State *L, const SVector3& v)
+  {
+    lua_createtable(L, 3, 0);
+    for(size_t i = 0; i < 3; i++){
+      luaStack<double>::push(L, v[i]);
+      lua_rawseti(L, 2, i + 1);
+    }
+  }
+  static std::string getName()
+  {
+    return "3-uple of double";
+  }
+};
+
 template<>
 class luaStack<std::string>{
   public:
diff --git a/Numeric/simpleFunction.h b/Numeric/simpleFunction.h
index 4960b290d05a7e7a0d40e1a0cf28a3bed88572d1..aba7c200c3711472d899416cc7fd29de815dfcd0 100644
--- a/Numeric/simpleFunction.h
+++ b/Numeric/simpleFunction.h
@@ -24,6 +24,29 @@ class simpleFunction {
   { dfdx = dfdy = dfdz = 0.0; }*/
 };
 
+#include "GmshConfig.h"
+#ifdef HAVE_LUA
+#include "LuaBindings.h"
+template <class scalar>
+class simpleFunctionLua:public simpleFunction<scalar> {
+  lua_State *_L;
+  std::string _luaFunctionName;
+  public:
+  scalar operator () (double x, double y, double z) const {
+    lua_getfield(_L, LUA_GLOBALSINDEX, _luaFunctionName.c_str());
+    luaStack<double>::push(_L, x);
+    luaStack<double>::push(_L, y);
+    luaStack<double>::push(_L, z);
+    lua_call(_L, 3, 1);
+    return luaStack<scalar>::get(_L,-1);
+  }
+  simpleFunctionLua (lua_State *L, const std::string luaFunctionName, scalar s):simpleFunction<scalar>(s) {
+    _L = L;
+    _luaFunctionName = luaFunctionName;
+  }
+};
+#endif
+
 template <class scalar>
 class simpleFunctionOnElement : public simpleFunction<scalar>
 {
diff --git a/Post/PView.cpp b/Post/PView.cpp
index 3135456160404c957646593be8ccc6d88579a208..cb8c78e56c088b36787283363ccb58a9f993907b 100644
--- a/Post/PView.cpp
+++ b/Post/PView.cpp
@@ -311,3 +311,12 @@ PView *PView::getViewByNum(int num, int timeStep, int partition)
   return 0;
 }
 
+#include "Bindings.h"
+void PView::registerBindings(binding *b) {
+  classBinding *cb = b->addClass<PView>("PView");
+  cb->setDescription("A post-processing view");
+  methodBinding *cm;
+  cm = cb->addMethod("write",&PView::write);
+  cm->setArgNames("fileName","format","append",NULL);
+  cm->setDescription("write data to a file. Format can be : 0 for ascii pos file, 1 for binary pos file, 2 for parsed pos file, 3 for STL, 4 for TXT, 5 for MSH and 6 for MED files. 'append' option is only supported for pos format.");
+}
diff --git a/Post/PView.h b/Post/PView.h
index 4a29eb033f10bafcbeec933e6fa614ade255b6d9..a3bc1710f82fda67e5a1f7711c18dacac8327f72 100644
--- a/Post/PView.h
+++ b/Post/PView.h
@@ -19,6 +19,7 @@ class GModel;
 class GMSH_PostPlugin;
 class ConnectionManager;
 
+class binding;
 // A post-processing view.
 class PView{
  private:
@@ -124,6 +125,7 @@ class PView{
 
   // smoothed normals
   smooth_normals *normals;
+  static void registerBindings(binding *b);
 };
 
 // this is the maximum number of nodes of elements we actually *draw*
diff --git a/Solver/elasticitySolver.cpp b/Solver/elasticitySolver.cpp
index ad53fd9bd3933b31a26667a1b0b5fd1baa710870..7343015894178253fc29eacc4a7b103c78c1e84a 100644
--- a/Solver/elasticitySolver.cpp
+++ b/Solver/elasticitySolver.cpp
@@ -24,6 +24,7 @@
 #include "PViewData.h"
 #endif
 
+/********************* deprecated api ? ****************************************/
 static void printLinearSystem(linearSystemCSRTaucs<double> *lsys)
 {
   int *startIndex;
@@ -65,13 +66,50 @@ void elasticitySolver::setMesh(const std::string &meshFileName)
   LagrangeMultiplierSpace = new ScalarLagrangeFunctionSpace(_tag+1);
 }
 
+void elasticitySolver::solve()
+{
+  linearSystemFull<double> *lsys = new linearSystemFull<double>;
+  /*
+#if defined(HAVE_TAUCS)
+  linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>;
+#elif defined(HAVE_PETSC)
+  linearSystemPETSc<double> *lsys = new linearSystemPETSc<double>;
+#else
+  linearSystemGmm<double> *lsys = new linearSystemGmm<double>;
+  lsys->setNoisy(2);
+#endif
+  */
+  assemble(lsys);
+  lsys->systemSolve();
+  printf("-- done solving!\n");
+  GaussQuadrature Integ_Bulk(GaussQuadrature::GradGrad);
+
+//   printLinearSystem(lsys);
+
+  double energ=0;
+  for (unsigned int i = 0; i < elasticFields.size(); i++)
+  {
+    SolverField<SVector3> Field(pAssembler, LagSpace);
+    IsotropicElasticTerm Eterm(Field,elasticFields[i]._E,elasticFields[i]._nu);
+    BilinearTermToScalarTerm<SVector3,SVector3> Elastic_Energy_Term(Eterm);
+    Assemble(Elastic_Energy_Term,elasticFields[i].g->begin(),elasticFields[i].g->end(),Integ_Bulk,energ);
+  }
+  printf("elastic energy=%f\n",energ);
+}
+
 void elasticitySolver::readInputFile(const std::string &fn)
 {
   FILE *f = fopen(fn.c_str(), "r");
   char what[256];
   while(!feof(f)){
     if(fscanf(f, "%s", what) != 1) return;
-    if (!strcmp(what, "ElasticDomain")){
+    if(what[0]=='#'){
+      char *line=NULL;
+      size_t l = 0;
+      int r = getline(&line,&l,f);
+      free(line);
+    }
+    else if (!strcmp(what, "ElasticDomain")){
       elasticField field;
       int physical;
       if(fscanf(f, "%d %lf %lf", &physical, &field._E, &field._nu) != 3) return;
@@ -79,7 +117,7 @@ void elasticitySolver::readInputFile(const std::string &fn)
       field.g = new groupOfElements (_dim, physical);
       elasticFields.push_back(field);
     }
-    if (!strcmp(what, "LagrangeMultipliers")){
+    else if (!strcmp(what, "LagrangeMultipliers")){
       LagrangeMultiplierField field;
       int physical;
       double d1, d2, d3, val;
@@ -106,7 +144,7 @@ void elasticitySolver::readInputFile(const std::string &fn)
       if(fscanf(f, "%d %d %lf", &node, &comp, &val) != 3) return;
       dirichletBC diri;
       diri.g = new groupOfElements (0, node);
-      diri._f= simpleFunction<double>(val);
+      diri._f= new simpleFunction<double>(val);
       diri._comp=comp;
       diri._tag=node;
       diri.onWhat=BoundaryCondition::ON_VERTEX;
@@ -118,7 +156,7 @@ void elasticitySolver::readInputFile(const std::string &fn)
       if(fscanf(f, "%d %d %lf", &edge, &comp, &val) != 3) return;
       dirichletBC diri;
       diri.g = new groupOfElements (1, edge);
-      diri._f= simpleFunction<double>(val);
+      diri._f= new simpleFunction<double>(val);
       diri._comp=comp;
       diri._tag=edge;
       diri.onWhat=BoundaryCondition::ON_EDGE;
@@ -130,7 +168,7 @@ void elasticitySolver::readInputFile(const std::string &fn)
       if(fscanf(f, "%d %d %lf", &face, &comp, &val) != 3) return;
       dirichletBC diri;
       diri.g = new groupOfElements (2, face);
-      diri._f= simpleFunction<double>(val);
+      diri._f= new simpleFunction<double>(val);
       diri._comp=comp;
       diri._tag=face;
       diri.onWhat=BoundaryCondition::ON_FACE;
@@ -142,7 +180,7 @@ void elasticitySolver::readInputFile(const std::string &fn)
       if(fscanf(f, "%d %lf %lf %lf", &node, &val1, &val2, &val3) != 4) return;
       neumannBC neu;
       neu.g = new groupOfElements (0, node);
-      neu._f= simpleFunction<SVector3>(SVector3(val1, val2, val3));
+      neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3));
       neu._tag=node;
       neu.onWhat=BoundaryCondition::ON_VERTEX;
       allNeumann.push_back(neu);
@@ -153,7 +191,7 @@ void elasticitySolver::readInputFile(const std::string &fn)
       if(fscanf(f, "%d %lf %lf %lf", &edge, &val1, &val2, &val3) != 4) return;
       neumannBC neu;
       neu.g = new groupOfElements (1, edge);
-      neu._f= simpleFunction<SVector3>(SVector3(val1, val2, val3));
+      neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3));
       neu._tag=edge;
       neu.onWhat=BoundaryCondition::ON_EDGE;
       allNeumann.push_back(neu);
@@ -164,7 +202,7 @@ void elasticitySolver::readInputFile(const std::string &fn)
       if(fscanf(f, "%d %lf %lf %lf", &face, &val1, &val2, &val3) != 4) return;
       neumannBC neu;
       neu.g = new groupOfElements (2, face);
-      neu._f= simpleFunction<SVector3>(SVector3(val1, val2, val3));
+      neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3));
       neu._tag=face;
       neu.onWhat=BoundaryCondition::ON_FACE;
       allNeumann.push_back(neu);
@@ -175,7 +213,7 @@ void elasticitySolver::readInputFile(const std::string &fn)
       if(fscanf(f, "%d %lf %lf %lf", &volume, &val1, &val2, &val3) != 4) return;
       neumannBC neu;
       neu.g = new groupOfElements (3, volume);
-      neu._f= simpleFunction<SVector3>(SVector3(val1, val2, val3));
+      neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3));
       neu._tag=volume;
       neu.onWhat=BoundaryCondition::ON_VOLUME;
       allNeumann.push_back(neu);
@@ -200,26 +238,96 @@ void elasticitySolver::readInputFile(const std::string &fn)
       pModel = pModel->buildCutGModel(&ls);
     }
     else {
-      Msg::Error("Invalid input : %s", what);
+      Msg::Error("Invalid input : '%s'", what);
 //      return;
     }
   }
   fclose(f);
 }
 
-void elasticitySolver::solve()
+/********************* end deprecated api ****************************************/
+
+void elasticitySolver::addDirichletBC (int dim, int entityId, int component, double value) {
+  dirichletBC diri;
+  diri.g = new groupOfElements (dim, entityId);
+  diri._f= new simpleFunction<double>(value);
+  diri._comp=component;
+  diri._tag=entityId;
+  switch (dim) {
+    case 0 : diri.onWhat=BoundaryCondition::ON_VERTEX; break;
+    case 1 : diri.onWhat=BoundaryCondition::ON_EDGE; break;
+    case 2 : diri.onWhat=BoundaryCondition::ON_FACE; break;
+    default : return;
+  }
+  allDirichlet.push_back(diri);
+}
+
+void elasticitySolver::addDirichletBCLua (int dim, int entityId, int component, std::string luaFunctionName, lua_State *L) {
+  dirichletBC diri;
+  diri.g = new groupOfElements (dim, entityId);
+  diri._f= new simpleFunctionLua<double>(L, luaFunctionName,0.);
+  diri._comp=component;
+  diri._tag=entityId;
+  switch (dim) {
+    case 0 : diri.onWhat=BoundaryCondition::ON_VERTEX; break;
+    case 1 : diri.onWhat=BoundaryCondition::ON_EDGE; break;
+    case 2 : diri.onWhat=BoundaryCondition::ON_FACE; break;
+    default : return;
+  }
+  allDirichlet.push_back(diri);
+}
+
+void elasticitySolver::addNeumannBC (int dim, int entityId, const std::vector<double> value) {
+  if(value.size()!=3) return;
+  neumannBC neu;
+  neu.g = new groupOfElements (dim, entityId);
+  neu._f= new simpleFunction<SVector3>(SVector3(value[0], value[1], value[2]));
+  neu._tag=entityId;
+  switch (dim) {
+    case 0 : neu.onWhat=BoundaryCondition::ON_VERTEX; break;
+    case 1 : neu.onWhat=BoundaryCondition::ON_EDGE; break;
+    case 2 : neu.onWhat=BoundaryCondition::ON_FACE; break;
+    default : return;
+  }
+  allNeumann.push_back(neu);
+}
+
+void elasticitySolver::addNeumannBCLua (int dim, int entityId, std::string luaFunctionName, lua_State *L) {
+  neumannBC neu;
+  neu.g = new groupOfElements (dim, entityId);
+  neu._f= new simpleFunctionLua<SVector3>(L, luaFunctionName, SVector3(0,0,0));
+  neu._tag=entityId;
+  switch (dim) {
+    case 0 : neu.onWhat=BoundaryCondition::ON_VERTEX; break;
+    case 1 : neu.onWhat=BoundaryCondition::ON_EDGE; break;
+    case 2 : neu.onWhat=BoundaryCondition::ON_FACE; break;
+    default : return;
+  }
+  allNeumann.push_back(neu);
+}
+
+void elasticitySolver::addElasticDomain (int physical, double e, double nu){
+  elasticField field;
+  field._tag = _tag;
+  field._E = e;
+  field._nu = nu;
+  field.g = new groupOfElements (_dim, physical);
+  elasticFields.push_back(field);
+}
+
+elasticitySolver::elasticitySolver(GModel *model, int tag)
+{
+  pModel = model;
+  _dim = pModel->getNumRegions() ? 3 : 2;
+  _tag = tag;
+  pAssembler = NULL;
+  if (_dim==3) LagSpace=new VectorLagrangeFunctionSpace(_tag);
+  if (_dim==2) LagSpace=new VectorLagrangeFunctionSpace(_tag,VectorLagrangeFunctionSpace::VECTOR_X,VectorLagrangeFunctionSpace::VECTOR_Y);
+  LagrangeMultiplierSpace = new ScalarLagrangeFunctionSpace(_tag+1);
+}
+
+void elasticitySolver::assemble(linearSystem<double> *lsys)
 {
-  linearSystemFull<double> *lsys = new linearSystemFull<double>;
-  /*
-#if defined(HAVE_TAUCS)
-  linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>;
-#elif defined(HAVE_PETSC)
-  linearSystemPETSc<double> *lsys = new linearSystemPETSc<double>;
-#else
-  linearSystemGmm<double> *lsys = new linearSystemGmm<double>;
-  lsys->setNoisy(2);
-#endif
-  */
   if (pAssembler) delete pAssembler;
   pAssembler = new dofManager<double>(lsys);
 
@@ -231,7 +339,7 @@ void elasticitySolver::solve()
   for (unsigned int i = 0; i < allDirichlet.size(); i++)
   {
     FilterDofComponent filter(allDirichlet[i]._comp);
-    FixNodalDofs(*LagSpace,allDirichlet[i].g->begin(),allDirichlet[i].g->end(),*pAssembler,allDirichlet[i]._f,filter);
+    FixNodalDofs(*LagSpace,allDirichlet[i].g->begin(),allDirichlet[i].g->end(),*pAssembler,*allDirichlet[i]._f,filter);
   }
   // LagrangeMultipliers
   for (unsigned int i = 0; i < LagrangeMultiplierFields.size(); ++i)
@@ -255,7 +363,7 @@ void elasticitySolver::solve()
   std::cout <<  "Neumann BC"<< std::endl;
   for (unsigned int i = 0; i < allNeumann.size(); i++)
   {
-    LoadTerm<SVector3> Lterm(*LagSpace,allNeumann[i]._f);
+    LoadTerm<SVector3> Lterm(*LagSpace,*allNeumann[i]._f);
     Assemble(Lterm,*LagSpace,allNeumann[i].g->begin(),allNeumann[i].g->end(),Integ_Boundary,*pAssembler);
   }
   // Assemble cross term, laplace term and rhs term for LM
@@ -281,32 +389,18 @@ void elasticitySolver::solve()
     Assemble(Eterm,*LagSpace,elasticFields[i].g->begin(),elasticFields[i].g->end(),Integ_Bulk,*pAssembler);
   }
 
-  for (int i=0;i<pAssembler->sizeOfR();i++){
+  /*for (int i=0;i<pAssembler->sizeOfR();i++){
     for (int j=0;j<pAssembler->sizeOfR();j++){
       double d;lsys->getFromMatrix(i,j,d);
       printf("%12.5E ",d);
     }
     double d;lsys->getFromRightHandSide(i,d);
     printf(" |  %12.5E\n",d);
-  }
+  }*/
 
   printf("nDofs=%d\n",pAssembler->sizeOfR());
   printf("nFixed=%d\n",pAssembler->sizeOfF());
   printf("-- done assembling!\n");
-  lsys->systemSolve();
-  printf("-- done solving!\n");
-
-//   printLinearSystem(lsys);
-
-  double energ=0;
-  for (unsigned int i = 0; i < elasticFields.size(); i++)
-  {
-    SolverField<SVector3> Field(pAssembler, LagSpace);
-    IsotropicElasticTerm Eterm(Field,elasticFields[i]._E,elasticFields[i]._nu);
-    BilinearTermToScalarTerm<SVector3,SVector3> Elastic_Energy_Term(Eterm);
-    Assemble(Elastic_Energy_Term,elasticFields[i].g->begin(),elasticFields[i].g->end(),Integ_Bulk,energ);
-  }
-  printf("elastic energy=%f\n",energ);
 }
 
 
@@ -352,7 +446,7 @@ static double vonMises(dofManager<double> *a, MElement *e,
   return ComputeVonMises(s);
 }
 
-PView* elasticitySolver::buildDisplacementView (const std::string &postFileName)
+PView* elasticitySolver::buildDisplacementView (const std::string postFileName)
 {
   std::cout <<  "build Displacement View"<< std::endl;
   std::set<MVertex*> v;
@@ -396,7 +490,7 @@ PView* elasticitySolver::buildDisplacementView (const std::string &postFileName)
   return pv;
 }
 
-PView* elasticitySolver::buildLagrangeMultiplierView (const std::string &postFileName)
+PView* elasticitySolver::buildLagrangeMultiplierView (const std::string postFileName)
 {
   std::cout <<  "build Lagrange Multiplier View"<< std::endl;
   if(!LagrangeMultiplierSpace) return new PView();
@@ -424,7 +518,7 @@ PView* elasticitySolver::buildLagrangeMultiplierView (const std::string &postFil
   return pv;
 }
 
-PView *elasticitySolver::buildElasticEnergyView(const std::string &postFileName)
+PView *elasticitySolver::buildElasticEnergyView(const std::string postFileName)
 {
   std::cout <<  "build Elastic Energy View"<< std::endl;
   std::map<int, std::vector<double> > data;
@@ -454,7 +548,7 @@ PView *elasticitySolver::buildElasticEnergyView(const std::string &postFileName)
   return pv;
 }
 
-PView *elasticitySolver::buildVonMisesView(const std::string &postFileName)
+PView *elasticitySolver::buildVonMisesView(const std::string postFileName)
 {std::cout <<  "build elastic view"<< std::endl;
   std::map<int, std::vector<double> > data;
   GaussQuadrature Integ_Bulk(GaussQuadrature::GradGrad);
@@ -506,7 +600,6 @@ PView* elasticitySolver::buildVonMisesView(const std::string &postFileName)
 }
 #endif
 
-
 #include "Bindings.h"
 void elasticitySolverRegisterBindings(binding *b) 
 {
@@ -519,12 +612,52 @@ void elasticitySolverRegisterBindings(binding *b)
   cm->setDescription ("reads an input file");
   cm->setArgNames("fileName",NULL);
 
-  cm = cb->addMethod("solve", &elasticitySolver::solve);
-  cm->setDescription ("solves the problem");
+  cm = cb->addMethod("assemble", &elasticitySolver::assemble);
+  cm->setDescription ("assembles the problem");
+  cm->setArgNames ("linearSystem",NULL);
 
-  cm = cb->setConstructor<elasticitySolver,int>();
-  cm->setDescription ("A new elasticitySolver. The parameter is the unknowns tag");
-  cm->setArgNames("tag",NULL);
+  cm = cb->addMethod("addDirichletBC", &elasticitySolver::addDirichletBC);
+  cm->setDescription ("add a Dirichlet (displacement) boundary condition on a given entity");
+  cm->setArgNames ("dim", "entityId", "component", "value", NULL);
+
+  cm = cb->addMethod("addDirichletBCLua", &elasticitySolver::addDirichletBCLua);
+  cm->setDescription ("add a Dirichlet (displacement) boundary condition on a given entity. The lua function takes x,y,z as arguments and return the displacement value.");
+  cm->setArgNames ("dim", "entityId", "component", "luaFunctionName", NULL);
 
+  cm = cb->addMethod("addNeumannBC", &elasticitySolver::addNeumannBC);
+  cm->setDescription ("add a Neumann (force) boundary condition on a given entity. Size of value has to be 3.");
+  cm->setArgNames ("dim", "entityId", "value", NULL);
+
+  cm = cb->addMethod("addNeumannBCLua", &elasticitySolver::addNeumannBCLua);
+  cm->setDescription ("add a Neumann (force) boundary condition on a given entity. The lua function takes x,y,z as arguments and return a vector with the 3 components of the force.");
+  cm->setArgNames ("dim", "entityId", "luaFunctionName", NULL);
+
+  cm = cb->addMethod("addElasticDomain", &elasticitySolver::addElasticDomain);
+  cm->setDescription ("add an elastic region with parameters E and nu");
+  cm->setArgNames ("tag", "E", "nu", NULL);
+
+#if defined HAVE_POST
+
+  cm = cb->addMethod ("buildVonMisesView", &elasticitySolver::buildVonMisesView);
+  cm->setDescription ("create a new view.");
+  cm->setArgNames ("fileName", NULL);
+
+  cm = cb->addMethod ("buildDisplacementView", &elasticitySolver::buildDisplacementView);
+  cm->setDescription ("create a new view."); 
+  cm->setArgNames ("fileName", NULL);
+
+  cm = cb->addMethod ("buildLagrangeMultiplierView", &elasticitySolver::buildLagrangeMultiplierView);
+  cm->setDescription ("create a new view.");
+  cm->setArgNames ("fileName", NULL);
+
+  cm = cb->addMethod ("buildElasticEnergyView", &elasticitySolver::buildElasticEnergyView);
+  cm->setDescription ("create a new view.");
+  cm->setArgNames ("fileName", NULL);
+
+#endif
+
+  cm = cb->setConstructor<elasticitySolver,GModel*,int>();
+  cm->setDescription ("A new elasticitySolver. The parameter is the unknowns tag");
+  cm->setArgNames("model","tag",NULL);
 }
 
diff --git a/Solver/elasticitySolver.h b/Solver/elasticitySolver.h
index 8df295dc57e1d317ee11830c3c6cdc261fd1b4fd..3694fdbd30160ba81e7fe3edff60701bc0a9b6f0 100644
--- a/Solver/elasticitySolver.h
+++ b/Solver/elasticitySolver.h
@@ -45,14 +45,15 @@ struct BoundaryCondition
 struct dirichletBC : public BoundaryCondition
 {
   int _comp; // component
-  simpleFunction<double> _f;
-  dirichletBC () :BoundaryCondition(),_comp(0),_f(0){}
+  simpleFunction<double> *_f;
+  dirichletBC ():BoundaryCondition(),_comp(0),_f(0){}
+  dirichletBC (int dim, int entityId, int component, double value);
 };
 
 struct neumannBC  : public BoundaryCondition
 {
-  simpleFunction<SVector3> _f;
-  neumannBC () : BoundaryCondition(),_f(SVector3(0,0,0)){}
+  simpleFunction<SVector3> *_f;
+  neumannBC () : BoundaryCondition(),_f(NULL){}
 };
 
 // an elastic solver ...
@@ -75,20 +76,29 @@ class elasticitySolver
   
  public:
   elasticitySolver(int tag) : _tag(tag),LagSpace(0),pAssembler(0),LagrangeMultiplierSpace(0) {}
+
+  elasticitySolver(GModel *model, int tag);
+  void addDirichletBC (int dim, int entityId, int component, double value);
+  void addDirichletBCLua (int dim, int entityId, int component, std::string luaFunctionName, lua_State *L);
+  void addNeumannBC (int dim, int entityId, const std::vector<double> value);
+  void addNeumannBCLua (int dim, int entityId, std::string luaFunctionName, lua_State *L);
+  void addElasticDomain (int tag, double e, double nu);
+
   virtual ~elasticitySolver()
   {
     if (LagSpace) delete LagSpace;
     if (LagrangeMultiplierSpace) delete LagrangeMultiplierSpace;
     if (pAssembler) delete pAssembler;
   }
+  void assemble (linearSystem<double> *lsys);
   void readInputFile(const std::string &meshFileName);
   void read(const std::string s) {readInputFile(s.c_str());}
   virtual void setMesh(const std::string &meshFileName);
   void solve();
-  virtual PView *buildDisplacementView(const std::string &postFileName);
-  virtual PView *buildLagrangeMultiplierView(const std::string &posFileName);
-  virtual PView *buildElasticEnergyView(const std::string &postFileName);
-  virtual PView *buildVonMisesView(const std::string &postFileName);
+  virtual PView *buildDisplacementView(const std::string postFileName);
+  virtual PView *buildLagrangeMultiplierView(const std::string posFileName);
+  virtual PView *buildElasticEnergyView(const std::string postFileName);
+  virtual PView *buildVonMisesView(const std::string postFileName);
   // std::pair<PView *, PView*> buildErrorEstimateView
   //   (const std::string &errorFileName, double, int);
   // std::pair<PView *, PView*> buildErrorEstimateView
diff --git a/benchmarks/elasticity/conge.geo b/benchmarks/elasticity/conge.geo
new file mode 100644
index 0000000000000000000000000000000000000000..ca3c052d2856abd298f7f2a674a619e5f0f3df6c
--- /dev/null
+++ b/benchmarks/elasticity/conge.geo
@@ -0,0 +1,94 @@
+
+Mesh.CharacteristicLengthFromCurvature = 0;
+Mesh.CharacteristicLengthFromPoints = 1;
+Mesh.CharacteristicLengthExtendFromBoundary = 1;
+
+unit = 1.0e-02 ;
+
+e1 =  4.5 * unit ;
+e2 =  6.0 * unit / 2.0 ;
+e3 =  5.0 * unit / 2.0 ;
+h1 =  5.0 * unit ;
+h2 = 10.0 * unit ;
+h3 =  5.0 * unit ;
+//h4 =  1.0 * unit ;
+h4 =  2.0 * unit ;
+h5 =  4.5 * unit ;
+R1 =  1.0 * unit ;
+R2 =  1.5 * unit ;
+//R2 =  1.5 * unit ;
+r  =  2 * unit ;
+ccos = (-h5*R1+e2* (h5*h5+e2*e2-R1*R1)^0.5) / (h5*h5+e2*e2) ;
+ssin = ( 1.0 - ccos*ccos )^0.5 ;
+
+eps = 0.01 * unit;
+
+Lc1 = 0.001 ;
+Lc2 = 0.001 ;
+
+Point(1) = { -e1-e2, 0.0  , 0.0 , Lc1};
+Point(2) = { -e1-e2, h1   , 0.0 , Lc1};
+Point(3) = { -e3-r , h1   , 0.0 , Lc2};
+Point(4) = { -e3-r , h1+r , 0.0 , Lc2};
+Point(5) = { -e3   , h1+r , 0.0 , Lc2};
+Point(6) = { -e3   , h1+h2-eps, 0.0 , Lc1};
+Point(7) = {  e3   , h1+h2, 0.0 , Lc1};
+Point(8) = {  e3   , h1+r , 0.0 , Lc2};
+Point(9) = {  e3+r , h1+r , 0.0 , Lc2};
+Point(10)= {  e3+r , h1   , 0.0 , Lc2};
+Point(11)= {  e1+e2, h1   , 0.0 , Lc1};
+Point(12)= {  e1+e2, 0.0  , 0.0 , Lc1};
+Point(13)= {  e2   , 0.0  , 0.0 , Lc1};
+
+Point(14)= {  R1 / ssin , h5+R1*ccos, 0.0 , Lc2};
+Point(15)= {  0.0       , h5        , 0.0 , Lc2};
+Point(16)= { -R1 / ssin , h5+R1*ccos, 0.0 , Lc2};
+Point(17)= { -e2        , 0.0       , 0.0 , Lc1};
+
+Point(18)= { -R2  , h1+h3   , 0.0 , Lc2};
+Point(19)= { -R2  , h1+h3+h4, 0.0 , Lc2};
+Point(20)= {  0.0 , h1+h3+h4, 0.0 , Lc2};
+Point(21)= {  R2  , h1+h3+h4, 0.0 , Lc2};
+Point(22)= {  R2  , h1+h3   , 0.0 , Lc2};
+Point(23)= {  0.0 , h1+h3   , 0.0 , Lc2};
+
+Point(24)= {  0 , h1+h3+h4+R2, 0.0 , Lc2};
+Point(25)= {  0 , h1+h3-R2,    0.0 , Lc2};
+
+Line(1)  = {1 ,17};    /* ux=uy=0 */
+Line(2)  = {17,16};
+Circle(3) = {14,15,16};
+Line(4)  = {14,13};
+Line(5)  = {13,12};    /* ux=uy=0 */
+Line(6)  = {12,11};
+Line(7)  = {11,10};
+Circle(8) = { 8, 9,10};
+Line(9)  = { 8, 7};
+Line(10) = { 7, 6};    /* T=10000 N */
+Line(11) = { 6, 5};
+Circle(12) = { 3, 4, 5};
+Line(13) = { 3, 2};
+Line(14) = { 2, 1};
+
+Line(15) = {18,19};
+Circle(16) = {21,20,24};
+Circle(17) = {24,20,19};
+Circle(18) = {18,23,25};
+Circle(19) = {25,23,22};
+Line(20) = {21,22};
+
+Line Loop(21) = {17,-15,18,19,-20,16};
+//Plane Surface(22) = {21};
+Line Loop(23) = {11,-12,13,14,1,2,-3,4,5,6,7,-8,9,10};
+Plane Surface(24) = {23,21};
+
+//Physical Line(25) = {9,1,2,3,4,5,6,7,8,11,12,13,14,15,16,17,18,19,20,10};
+//Physical Surface(26) = {22,24};
+Physical Line(9) = {11};
+Physical Line(10) = {10};
+Physical Line(8) = {1, 5};
+Physical Surface(7) = {24};
+Physical Point(20) = {2};
+Physical Point(21) = {11};
+// Physical Line(25) = {11, 12, 13, 14};
+
diff --git a/benchmarks/elasticity/conge.lua b/benchmarks/elasticity/conge.lua
new file mode 100644
index 0000000000000000000000000000000000000000..121a0271315b88e94beaf8b4c104e9b5ca8c706d
--- /dev/null
+++ b/benchmarks/elasticity/conge.lua
@@ -0,0 +1,21 @@
+function neumannCondition (x,y,z)
+  return {-100e6,0,0}
+end
+
+m = GModel()
+m:load("conge.geo")
+m:load("conge.msh")
+e = elasticitySolver(m,1)
+e:addElasticDomain (7, 200e9, 0.3)
+e:addDirichletBC (1,8,0,0)
+e:addDirichletBC (1,8,1,0)
+e:addDirichletBC (1,8,2,0)
+e:addNeumannBCLua (1,9,"neumannCondition")
+sys = linearSystemCSRTaucs()
+e:assemble(sys)
+sys:systemSolve()
+view = e:buildVonMisesView("vonMises")
+view = e:buildDisplacementView("displacement")
+view = e:buildLagrangeMultiplierView("lagrangeMultiplier")
+view = e:buildElasticEnergyView("elasticEnergy")
+--view:write("test.pos",2,false)