diff --git a/Solver/linearSystemCSR.cpp b/Solver/linearSystemCSR.cpp
index 9cb38e7ecd4d9f95dfece6df82994c88a642b894..26700358043419ea93222e958bcb499ad358c459 100644
--- a/Solver/linearSystemCSR.cpp
+++ b/Solver/linearSystemCSR.cpp
@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <complex>
 #include "GmshConfig.h"
 #include "GmshMessage.h"
 #include "linearSystemCSR.h"
@@ -135,6 +136,49 @@ void linearSystemCSR<double>::preAllocateEntries ()
   }
 }
 
+template<>
+void linearSystemCSR<std::complex<double> >::preAllocateEntries ()
+{
+  if (_entriesPreAllocated) return;
+  if (_sparsity.getNbRows() == 0) return;
+  INDEX_TYPE nnz = 0;
+  int nbRows = _b->size();
+  for (int i = 0; i < nbRows; i++){
+    int nInRow;
+    _sparsity.getRow (i, nInRow);
+    nnz += nInRow;
+  }
+  CSRList_Resize_strict (_ai, nnz);
+  CSRList_Resize_strict (_ptr, nnz);
+  INDEX_TYPE *jptr = (INDEX_TYPE*) _jptr->array;
+  INDEX_TYPE *ai = (INDEX_TYPE*) _ai->array;
+  INDEX_TYPE *ptr = (INDEX_TYPE*) _ptr->array;
+  jptr[0] = 0;
+  nnz = 0;
+  for (int i = 0; i < nbRows; i++){
+    int nInRow;
+    const int *row = _sparsity.getRow (i, nInRow);
+    for (int j = 0; j < nInRow; j++) {
+      ai[nnz] = row[j];
+      ptr[nnz] = nnz+1;
+      nnz ++;
+    }
+    if (nInRow != 0)
+      ptr[nnz - 1] = 0;
+    jptr[i + 1] = nnz;
+    something[i] = (nInRow == 0 ? 0 : 1);
+  }
+  _entriesPreAllocated = true;
+  sorted = true;
+  _sparsity.clear();
+  // we do this after _sparsity.clear so that the peak memory usage is reduced
+  CSRList_Resize_strict (_a, nnz);
+  std::complex<double> *a = ( std::complex<double> * ) _a->array;
+  for (int i = 0; i < nnz; i++) {
+    a[i] = std::complex<double>();
+  }
+}
+
 template<>
 void linearSystemCSR<double>::allocate(int nbRows)
 {
@@ -173,6 +217,44 @@ void linearSystemCSR<double>::allocate(int nbRows)
   _x = new std::vector<double>(nbRows);
 }
 
+template<>
+void linearSystemCSR<std::complex<double> >::allocate(int nbRows)
+{
+  if(_a) {
+    CSRList_Delete(_a);
+    CSRList_Delete(_ai);
+    CSRList_Delete(_ptr);
+    CSRList_Delete(_jptr);
+    delete _x;
+    delete _b;
+    delete[] something;
+  }
+
+  if(nbRows == 0){
+    _a = 0;
+    _ai = 0;
+    _ptr = 0;
+    _jptr = 0;
+    _b = 0;
+    _x = 0;
+    sorted = false;
+    something = 0;
+    return;
+  }
+
+  _a    = CSRList_Create(nbRows, nbRows, sizeof(std::complex<double>));
+  _ai   = CSRList_Create(nbRows, nbRows, sizeof(INDEX_TYPE));
+  _ptr  = CSRList_Create(nbRows, nbRows, sizeof(INDEX_TYPE));
+  _jptr = CSRList_Create(nbRows + 1, nbRows, sizeof(INDEX_TYPE));
+
+  something = new char[nbRows];
+
+  for (int i = 0; i < nbRows; i++) something[i] = 0;
+
+  _b = new std::vector<std::complex<double> >(nbRows);
+  _x = new std::vector<std::complex<double> >(nbRows);
+}
+
 const int NSTACK = 50;
 const unsigned int M_sort2 = 7;
 
@@ -339,6 +421,18 @@ void linearSystemCSR<double>::getMatrix(INDEX_TYPE*& jptr,INDEX_TYPE*& ai,double
   sorted = true;
 }
 
+template<>
+void linearSystemCSR<std::complex<double> >::getMatrix(INDEX_TYPE*& jptr,INDEX_TYPE*& ai,double *& a)
+{
+  jptr = (INDEX_TYPE*) _jptr->array;
+  ai = (INDEX_TYPE*) _ai->array;
+  a = ( double  * ) _a->array;
+  if (!sorted)
+    sortColumns_(_b->size(), CSRList_Nbr(_a), (INDEX_TYPE *) _ptr->array, jptr,
+                 ai, (std::complex<double> *)a);
+  sorted = true;
+}
+
 #if defined(HAVE_GMM)
 
 #include "gmm.h"
@@ -417,4 +511,43 @@ int linearSystemCSRTaucs<double>::systemSolve()
   return 1;
 }
 
+template<>
+int linearSystemCSRTaucs<std::complex<double> >::systemSolve()
+{
+  if (!_a)return 1;
+  if(!sorted){
+    sortColumns_(_b->size(),
+                CSRList_Nbr(_a),
+                (INDEX_TYPE *) _ptr->array,
+                (INDEX_TYPE *) _jptr->array,
+                (INDEX_TYPE *) _ai->array,
+                (std::complex<double>*) _a->array);
+  }
+  sorted = true;
+
+  taucs_ccs_matrix myVeryCuteTaucsMatrix;
+  myVeryCuteTaucsMatrix.n = myVeryCuteTaucsMatrix.m = _b->size();
+  //myVeryCuteTaucsMatrix.rowind = (INDEX_TYPE*)_ptr->array;
+  //myVeryCuteTaucsMatrix.colptr = (INDEX_TYPE*)_ai->array;
+  myVeryCuteTaucsMatrix.rowind = (INDEX_TYPE*)_ai->array;
+  myVeryCuteTaucsMatrix.colptr = (INDEX_TYPE*)_jptr->array;
+  myVeryCuteTaucsMatrix.values.z = (taucs_dcomplex*)_a->array;
+  myVeryCuteTaucsMatrix.flags = TAUCS_SYMMETRIC | TAUCS_LOWER | TAUCS_DCOMPLEX;
+  char* options[] = { (char*)"taucs.factor.mf=true", NULL };
+  double t1 = Cpu();
+  int result = taucs_linsolve(&myVeryCuteTaucsMatrix,
+                              NULL,
+                              1,
+                              &(*_x)[0],
+                              &(*_b)[0],
+                              options,
+                              NULL);
+  double t2 = Cpu();
+  Msg::Debug("TAUCS has solved %d unknowns in %8.3f seconds", _b->size(), t2 - t1);
+  if (result != TAUCS_SUCCESS){
+    Msg::Error("Taucs Was Not Successfull %d", result);
+  }
+  return 1;
+}
+
 #endif
diff --git a/Solver/linearSystemCSR.h b/Solver/linearSystemCSR.h
index 6c05e03643640ecbaf49b0cea18c2b024f108e0d..52f286600c49daae5e60b6774fefc4ac42dc7d6b 100644
--- a/Solver/linearSystemCSR.h
+++ b/Solver/linearSystemCSR.h
@@ -12,6 +12,7 @@
 #include "linearSystem.h"
 #include "sparsityPattern.h"
 
+
 typedef int INDEX_TYPE ;
 typedef struct {
   int nmax;
@@ -53,6 +54,7 @@ class linearSystemCSR : public linearSystem<scalar> {
   virtual void preAllocateEntries ();
   virtual void addToMatrix(int il, int ic, const scalar &val) 
   {
+    
     if (!_entriesPreAllocated)
       preAllocateEntries();
     INDEX_TYPE  *jptr  = (INDEX_TYPE*) _jptr->array;
@@ -123,11 +125,11 @@ class linearSystemCSR : public linearSystem<scalar> {
   }
   virtual void addToRightHandSide(int row, const scalar &val)
   {
-    if(val != 0.0) (*_b)[row] += val;
+    if(val != scalar()) (*_b)[row] += val;
   }
   virtual void addToSolution(int row, const scalar &val)
   {
-    if(val != 0.0) (*_x)[row] += val;
+    if(val != scalar()) (*_x)[row] += val;
   }
   virtual void getFromRightHandSide(int row, scalar &val) const
   {
@@ -142,17 +144,17 @@ class linearSystemCSR : public linearSystem<scalar> {
     if (!_a) return;
     int N = CSRList_Nbr(_a);
     scalar *a = (scalar*) _a->array;
-    for (int i = 0; i < N; i++) a[i] = 0;
+    for (int i = 0; i < N; i++) a[i] = scalar();
   }
   virtual void zeroRightHandSide()
   {
     if (!_b) return;
-    for(unsigned int i = 0; i < _b->size(); i++) (*_b)[i] = 0.;
+    for(unsigned int i = 0; i < _b->size(); i++) (*_b)[i] = scalar();
   }
   virtual void zeroSolution()
   {
     if (!_x) return;
-    for(unsigned int i = 0; i < _x->size(); i++) (*_x)[i] = 0.;
+    for(unsigned int i = 0; i < _x->size(); i++) (*_x)[i] = scalar();
   }
 
   virtual double normInfRightHandSide() const
@@ -160,8 +162,7 @@ class linearSystemCSR : public linearSystem<scalar> {
     double nor = 0.;
     double temp;
     for(unsigned int i = 0; i < _b->size(); i++){
-      temp = (*_b)[i];
-      if(temp < 0) temp = -temp;
+      temp = std::abs((*_b)[i]);
       if(nor < temp) nor = temp;
     }
     return nor;
@@ -194,7 +195,7 @@ class linearSystemCSRTaucs : public linearSystemCSR<scalar> {
  public:
   linearSystemCSRTaucs(){}
   virtual ~linearSystemCSRTaucs(){}
-  virtual void addToMatrix(int il, int ic, const double &val)
+  virtual void addToMatrix(int il, int ic, const scalar &val)
   {
     if (il <= ic) {
       linearSystemCSR<scalar>::addToMatrix(il, ic, val);