diff --git a/src/algebra/BiCGStab.hpp b/src/algebra/BiCGStab.hpp
index c931385b214c91ca2807db4f07fca027ebd79b25..bc822668a7f63c4d5d7cc4c45f4d1b1d70084fc0 100644
--- a/src/algebra/BiCGStab.hpp
+++ b/src/algebra/BiCGStab.hpp
@@ -5,14 +5,19 @@
 #include <iomanip>
 #include <iostream>
 
+#include <rang.hpp>
+
+template <bool verbose = true>
 struct BiCGStab
 {
   template <typename VectorType, typename MatrixType>
   BiCGStab(const VectorType& b, const MatrixType& A, VectorType& x, const size_t max_iter, const double epsilon = 1e-6)
   {
-    std::cout << "- bi-conjugate gradient stabilized\n";
-    std::cout << "  epsilon = " << epsilon << '\n';
-    std::cout << "  maximum number of iterations: " << max_iter << '\n';
+    if constexpr (verbose) {
+      std::cout << "- bi-conjugate gradient stabilized\n";
+      std::cout << "  epsilon = " << epsilon << '\n';
+      std::cout << "  maximum number of iterations: " << max_iter << '\n';
+    }
 
     VectorType r_k_1{b.size()};
 
@@ -33,10 +38,14 @@ struct BiCGStab
 
       VectorType r_k{x.size()};
 
-      std::cout << "   initial residu: " << resid0 << '\n';
+      if constexpr (verbose) {
+        std::cout << "   initial residu: " << resid0 << '\n';
+      }
       for (size_t i = 1; i <= max_iter; ++i) {
-        std::cout << "  - iteration: " << std::setw(6) << i << "\tresidu: " << residu / resid0
-                  << "\tabsolute: " << residu << '\n';
+        if constexpr (verbose) {
+          std::cout << "  - iteration: " << std::setw(6) << i << "\tresidu: " << residu / resid0
+                    << "\tabsolute: " << residu << '\n';
+        }
 
         Ap_k = A * p_k;
 
@@ -64,14 +73,14 @@ struct BiCGStab
       }
 
       if (residu / resid0 > epsilon) {
-        std::cout << "  bi_conjugate gradient stabilized: *NOT CONVERGED*\n";
+        std::cout << "  bi-conjugate gradient stabilized: " << rang::fgB::red << "*NOT CONVERGED*" << rang::style::reset
+                  << '\n';
+        ;
         std::cout << "  - epsilon:          " << epsilon << '\n';
         std::cout << "  - relative residu : " << residu / resid0 << '\n';
         std::cout << "  - absolute residu : " << residu << '\n';
       }
     }
-
-    std::cout << "- bi-conjugate gradient stabilized: done\n";
   }
 };
 
diff --git a/src/algebra/PCG.hpp b/src/algebra/PCG.hpp
index 74c17ee40971b96c512c196d630f1edfadfa6ddc..36a4635b313d2bba13d97e1b7a4ea1882e2a66a2 100644
--- a/src/algebra/PCG.hpp
+++ b/src/algebra/PCG.hpp
@@ -4,6 +4,9 @@
 #include <iomanip>
 #include <iostream>
 
+#include <rang.hpp>
+
+template <bool verbose = true>
 struct PCG
 {
   template <typename VectorType, typename MatrixType, typename PreconditionerType>
@@ -14,14 +17,16 @@ struct PCG
       const size_t maxiter,
       const double epsilon = 1e-6)
   {
-    std::cout << "- conjugate gradient\n";
-    std::cout << "  epsilon = " << epsilon << '\n';
-    std::cout << "  maximum number of iterations: " << maxiter << '\n';
+    if constexpr (verbose) {
+      std::cout << "- conjugate gradient\n";
+      std::cout << "  epsilon = " << epsilon << '\n';
+      std::cout << "  maximum number of iterations: " << maxiter << '\n';
+    }
 
     VectorType h{f.size()};
     VectorType b = copy(f);
 
-    if (true) {
+    if constexpr (verbose) {
       h = A * x;
       h -= f;
       std::cout << "- initial *real* residu :   " << (h, h) << '\n';
@@ -69,10 +74,14 @@ struct PCG
       if ((i == 1) && (gcg != 0)) {
         relativeEpsilon = epsilon * gcg;
         gcg0            = gcg;
-        std::cout << "  initial residu: " << gcg << '\n';
+        if constexpr (verbose) {
+          std::cout << "  initial residu: " << gcg << '\n';
+        }
+      }
+      if constexpr (verbose) {
+        std::cout << "  - iteration " << std::setw(6) << i << "\tresidu: " << gcg / gcg0;
+        std::cout << "\tabsolute: " << gcg << '\n';
       }
-      std::cout << "  - iteration " << std::setw(6) << i << "\tresidu: " << gcg / gcg0;
-      std::cout << "\tabsolute: " << gcg << '\n';
 
       if (gcg < relativeEpsilon) {
         break;
@@ -85,7 +94,7 @@ struct PCG
     }
 
     if (gcg > relativeEpsilon) {
-      std::cout << "  conjugate gradient: *NOT CONVERGED*\n";
+      std::cout << "  conjugate gradient: " << rang::fgB::red << "*NOT CONVERGED*" << rang::style::reset << '\n';
       std::cout << "  - epsilon:          " << epsilon << '\n';
       std::cout << "  - relative residu : " << gcg / gcg0 << '\n';
       std::cout << "  - absolute residu : " << gcg << '\n';
diff --git a/src/mesh/MeshData.hpp b/src/mesh/MeshData.hpp
index df4246a0ee36f2277e50d34398bf6de7a8d5ad3f..c82e9ce06ec8b7d43ce1c6cc2fec282f89dc1fee 100644
--- a/src/mesh/MeshData.hpp
+++ b/src/mesh/MeshData.hpp
@@ -155,7 +155,7 @@ class MeshData : public IMeshData
   PUGS_INLINE
   void
   _computeCellCentroid()
-  {   // Computes vertices isobarycenter
+  {
     const CellValue<const Rd> cell_iso_barycenter = this->cellIsoBarycenter();
     if constexpr (Dimension == 1) {
       m_cell_centroid = cell_iso_barycenter;
@@ -190,8 +190,53 @@ class MeshData : public IMeshData
           });
         m_cell_centroid = cell_centroid;
       } else {
-        std::cout << rang::fgB::yellow << "Centroids are not computed correctly in 3d" << rang::style::reset << '\n';
-        m_cell_centroid = cell_iso_barycenter;
+        const auto& face_center           = this->xl();
+        const CellValue<const double> Vj  = this->Vj();
+        const NodeValue<const Rd>& xr     = m_mesh.xr();
+        const auto& cell_to_face_matrix   = m_mesh.connectivity().cellToFaceMatrix();
+        const auto& face_to_node_matrix   = m_mesh.connectivity().faceToNodeMatrix();
+        const auto& cell_face_is_reversed = m_mesh.connectivity().cellFaceIsReversed();
+
+        CellValue<Rd> cell_centroid{m_mesh.connectivity()};
+        parallel_for(
+          m_mesh.numberOfCells(), PUGS_LAMBDA(CellId j) {
+            const Rd xj = m_cell_iso_barycenter[j];
+
+            const auto& cell_faces = cell_to_face_matrix[j];
+
+            Rd sum = zero;
+            for (size_t i_face = 0; i_face < cell_faces.size(); ++i_face) {
+              const FaceId face_id = cell_faces[i_face];
+
+              const Rd xl = face_center[face_id];
+
+              const Rd xjxl = xl - xj;
+
+              const auto& face_nodes = face_to_node_matrix[face_id];
+
+              const Rd xl_plus_xj = xl + xj;
+
+              double sign = (cell_face_is_reversed(j, i_face)) ? -1 : 1;
+
+              for (size_t i_face_node = 0; i_face_node < face_nodes.size(); ++i_face_node) {
+                const Rd& xr0 = xr[face_nodes[i_face_node]];
+                const Rd& xr1 = xr[face_nodes[(i_face_node + 1) % face_nodes.size()]];
+
+                const Rd xjxr0 = xr0 - xj;
+                const Rd xjxr1 = xr1 - xj;
+
+                const double Vjlr = (crossProduct(xjxr0, xjxr1), xjxl);
+
+                sum += (sign * Vjlr) * (xl_plus_xj + xr0 + xr1);
+              }
+            }
+
+            sum *= 1 / (24 * Vj[j]);
+
+            cell_centroid[j] = sum;
+          });
+
+        m_cell_centroid = cell_centroid;
       }
     }
   }
diff --git a/tests/test_BiCGStab.cpp b/tests/test_BiCGStab.cpp
index b7cb2d3bd8afe280a7d8c416a662016851e0d820..99b94515ba7795903434db761d509b9052fcaf71 100644
--- a/tests/test_BiCGStab.cpp
+++ b/tests/test_BiCGStab.cpp
@@ -45,7 +45,7 @@ TEST_CASE("BiCGStab", "[algebra]")
     Vector<double> x{5};
     x = 0;
 
-    BiCGStab{b, A, x, 10, 1e-12};
+    BiCGStab<false>{b, A, x, 10, 1e-12};
     Vector error = x - x_exact;
     REQUIRE(std::sqrt((error, error)) < 1E-10 * std::sqrt((x, x)));
   }
diff --git a/tests/test_PCG.cpp b/tests/test_PCG.cpp
index 92c0b4caf10824c25a1bef352dcd86ca5151b1e5..acc48b91e7f362e2f24f830465a9e7fc7f53f6d3 100644
--- a/tests/test_PCG.cpp
+++ b/tests/test_PCG.cpp
@@ -64,7 +64,7 @@ TEST_CASE("PCG", "[algebra]")
     Vector<double> x{5};
     x = 0;
 
-    PCG{b, A, A, x, 10, 1e-12};
+    PCG<false>{b, A, A, x, 10, 1e-12};
     REQUIRE(std::sqrt((x, x)) == 0);
   }
 
@@ -106,7 +106,7 @@ TEST_CASE("PCG", "[algebra]")
     Vector<double> x{5};
     x = 0;
 
-    PCG{b, A, A, x, 1, 1e-12};
+    PCG<false>{b, A, A, x, 1, 1e-12};
     Vector error = x - x_exact;
     REQUIRE(std::sqrt((error, error)) > 1E-10 * std::sqrt((x, x)));
   }