diff --git a/Applications/CLI/CMakeLists.txt b/Applications/CLI/CMakeLists.txt
index edb87aa77c7ff8a7b3c1afdfeda1f8c8193aeccc..836daed4fc4d91f02b0737bf9dae3bad7e1b9d1c 100644
--- a/Applications/CLI/CMakeLists.txt
+++ b/Applications/CLI/CMakeLists.txt
@@ -11,4 +11,8 @@ TARGET_LINK_LIBRARIES(ogs
     ${Boost_LIBRARIES}
 )
 
+IF(OGS_USE_PETSC)
+    TARGET_LINK_LIBRARIES(ogs ${ogs} ${PETSC_LIBRARIES})
+ENDIF()
+
 INCLUDE(Tests.cmake)
diff --git a/Applications/Utils/FileConverter/FEFLOW2OGS.cpp b/Applications/Utils/FileConverter/FEFLOW2OGS.cpp
index 9e795298e48a1371b1c800992eef0633af85e516..77138e6b22a9b8554363cf5a6990109803d7cc12 100644
--- a/Applications/Utils/FileConverter/FEFLOW2OGS.cpp
+++ b/Applications/Utils/FileConverter/FEFLOW2OGS.cpp
@@ -80,7 +80,6 @@ int main (int argc, char* argv[])
 	unsigned long mem_with_mesh (mem_watch.getVirtMemUsage());
 	INFO("Mem for mesh: %i MB", (mem_with_mesh - mem_without_mesh)/(1024*1024));
 #endif
-	run_time.stop();
 	INFO("Time for reading: %f seconds.", run_time.elapsed());
 	INFO("Read %d nodes and %d elements.", mesh->getNNodes(), mesh->getNElements());
 
diff --git a/Applications/Utils/FileConverter/GMSH2OGS.cpp b/Applications/Utils/FileConverter/GMSH2OGS.cpp
index 5c8d280aa45c8228b7a2016a2fce9cd31cb1ced9..82e40ea7e2ca456deea8f200a1a5628da4b34e95 100644
--- a/Applications/Utils/FileConverter/GMSH2OGS.cpp
+++ b/Applications/Utils/FileConverter/GMSH2OGS.cpp
@@ -84,7 +84,7 @@ int main (int argc, char* argv[])
 	unsigned long mem_with_mesh (mem_watch.getVirtMemUsage());
 	INFO("Mem for mesh: %i MB", (mem_with_mesh - mem_without_mesh)/(1024*1024));
 #endif
-	run_time.stop();
+
 	INFO("Time for reading: %f seconds.", run_time.elapsed());
 	INFO("Read %d nodes and %d elements.", mesh->getNNodes(), mesh->getNElements());
 
diff --git a/BaseLib/CMakeLists.txt b/BaseLib/CMakeLists.txt
index 4ccc1008d13b462fc32378ac0faf42ad61436e4d..1fcbef437fae4fc58e5b15d08dda6f1b89ebd7ee 100644
--- a/BaseLib/CMakeLists.txt
+++ b/BaseLib/CMakeLists.txt
@@ -2,6 +2,10 @@
 
 GET_SOURCE_FILES(SOURCES)
 
+IF(NOT OGS_USE_PETSC)
+	list(REMOVE_ITEM SOURCES PETScWallClockTimer.h)
+ENDIF()
+
 LIST(APPEND SOURCES "${CMAKE_CURRENT_BINARY_DIR}/BuildInfo.cpp" BuildInfo.h)
 
 # Create the library
diff --git a/BaseLib/CPUTime.cpp b/BaseLib/CPUTime.cpp
deleted file mode 100644
index adbf4777f686c0e642519b39a465cfd642c71ee9..0000000000000000000000000000000000000000
--- a/BaseLib/CPUTime.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * \file
- * \author Thomas Fischer
- * \date   2012-05-10
- * \brief  Implementation of the CPUTime class.
- *
- * \copyright
- * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org)
- *            Distributed under a Modified BSD License.
- *              See accompanying file LICENSE.txt or
- *              http://www.opengeosys.org/project/license
- *
- */
-
-#include "CPUTime.h"
-
-namespace BaseLib {
-
-void CPUTime::start()
-{
-	_start = clock();
-}
-
-void CPUTime::stop()
-{
-	_stop = clock();
-}
-
-double CPUTime::elapsed()
-{
-	return (_stop-_start)/(double)(CLOCKS_PER_SEC);
-}
-
-} // end namespace BaseLib
diff --git a/BaseLib/CPUTime.h b/BaseLib/CPUTime.h
index ab76d96de3687d30b68da9c1353401310dcf9bc4..e527d3a8c7f8d608fc0e8b671bb68bc355994912 100644
--- a/BaseLib/CPUTime.h
+++ b/BaseLib/CPUTime.h
@@ -1,7 +1,8 @@
 /**
  * \file
  * \author Thomas Fischer
- * \date   2012-05-10
+ * \author Wenqing Wang
+ * \date   2012-05-10, 2014.10.10
  * \brief  Definition of the CPUTime class.
  *
  * \copyright
@@ -17,17 +18,26 @@
 
 #include <ctime>
 
-namespace BaseLib {
+namespace BaseLib
+{
 
+/// Record CPU time
 class CPUTime
 {
-public:
-	void start();
-    void stop();
-    double elapsed();
-private:
-	clock_t _start;
-	clock_t _stop;
+    public:
+        /// Start the timer.
+        void start()
+        {
+            _timer = - clock()/static_cast<double>(CLOCKS_PER_SEC);
+        }
+
+        /// Get the epalsed time after started.
+        double elapsed()
+        {
+            return _timer + clock()/static_cast<double>(CLOCKS_PER_SEC);
+        }
+    private:
+        double _timer = 0.;
 };
 
 } // end namespace BaseLib
diff --git a/BaseLib/RunTime.cpp b/BaseLib/RunTime.cpp
deleted file mode 100644
index a8a718ce113df2b944f5ad7cad4eef9da47bc768..0000000000000000000000000000000000000000
--- a/BaseLib/RunTime.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * \file
- * \author Thomas Fischer
- * \date   2012-05-10
- * \brief  Implementation of the RunTime class.
- *
- * \copyright
- * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org)
- *            Distributed under a Modified BSD License.
- *              See accompanying file LICENSE.txt or
- *              http://www.opengeosys.org/project/license
- *
- */
-
-#include "RunTime.h"
-
-namespace BaseLib {
-
-void RunTime::start()
-{
-#ifndef _MSC_VER
-	gettimeofday(&_start, 0);
-#else
-	_start = timeGetTime();
-#endif
-}
-
-void RunTime::stop()
-{
-#ifndef _MSC_VER
-	gettimeofday(&_stop, 0);
-#else
-	_stop = timeGetTime();
-#endif
-}
-
-double RunTime::elapsed()
-{
-#ifndef _MSC_VER
-	return (_stop.tv_sec + _stop.tv_usec/1000000.0 - (_start.tv_sec + _start.tv_usec/1000000.0));
-#else
-	return (_stop - _start) / 1000.0;
-#endif
-}
-
-} // end namespace BaseLib
diff --git a/BaseLib/RunTime.h b/BaseLib/RunTime.h
index f258503074fea561faa3b34f47927bc41f569479..96d9929528f3017da6c3eb64d60562f1c0f767ac 100644
--- a/BaseLib/RunTime.h
+++ b/BaseLib/RunTime.h
@@ -1,7 +1,8 @@
 /**
  * \file
  * \author Thomas Fischer
- * \date   2012-05-10
+ * \author Wenqing Wang
+ * \date   2012-05-10, 2014-10.10
  * \brief  Definition of the RunTime class.
  *
  * \copyright
@@ -15,28 +16,58 @@
 #ifndef RUNTIME_H
 #define RUNTIME_H
 
+#if defined(USE_MPI) || defined(USE_PETSC)
+#include <mpi.h>
+#else
 #ifndef _MSC_VER
 #include <sys/time.h>
 #else
 #include <windows.h>
 #endif
+#endif
 
-namespace BaseLib {
+namespace BaseLib
+{
 
+/// Record the running time.
 class RunTime
 {
-public:
-	void start();
-	void stop();
-	double elapsed();
-private:
+    public:
+        /// Start the timer.
+        void start()
+        {
+#if defined(USE_MPI) || defined(USE_PETSC)
+            _timer = -MPI_Wtime();
+#else
+#ifndef _MSC_VER
+            timeval t;
+            gettimeofday(&t, 0);
+            _timer = -t.tv_sec - t.tv_usec/1000000.0;
+#else
+            _timer = -timeGetTime()/1000.0;
+#endif
+#endif
+        }
+
+        /// Get the epalsed time after started.
+        double elapsed()
+        {
+#if defined(USE_MPI) || defined(USE_PETSC)
+            return _timer + MPI_Wtime();
+#else
 #ifndef _MSC_VER
-	timeval _start;
-	timeval _stop;
+            timeval t;
+            gettimeofday(&t, 0);
+            _timer += t.tv_sec + t.tv_usec/1000000.0;
+            return _timer;
 #else
-	unsigned long _start;
-	unsigned long _stop;
+            return _timer + timeGetTime()/1000.0;
+#endif
 #endif
+        }
+
+    private:
+        double _timer = 0.;
 };
 
 } // end namespace BaseLib
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9e02a35902842fb80f55733881a1aa0e492913e4..0e8b81cfba61ef140998aa9a845b55cbfc153b09 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -65,7 +65,7 @@ OPTION(OGS_NO_EXTERNAL_LIBS "Builds OGS without any external dependencies." OFF)
 # Linear solvers
 OPTION(OGS_USE_LIS "Use Lis" OFF)
 
-# Parallel computing
+# Parallel computing: vector and matrix algebraic caculation, solvers
 OPTION(OGS_USE_PETSC "Use PETSc routines" OFF)
 
 # Paralleization
@@ -122,6 +122,10 @@ IF(OGS_USE_LIS)
     INCLUDE_DIRECTORIES(SYSTEM ${LIS_INCLUDE_DIR})
 ENDIF()
 
+IF(OGS_USE_MPI)
+    ADD_DEFINITIONS(-DUSE_MPI)
+ENDIF()
+
 IF(OGS_USE_PETSC)
     ADD_DEFINITIONS(-DUSE_PETSC)
     SET(OGS_USE_MPI ON)
diff --git a/SimpleTests/MatrixTests/MatMult.cpp b/SimpleTests/MatrixTests/MatMult.cpp
index bdb2b33191ec0d219401ec95749f67aec62713c4..2fb35be53541699a52c26eb02e0be0efbf587b8a 100644
--- a/SimpleTests/MatrixTests/MatMult.cpp
+++ b/SimpleTests/MatrixTests/MatMult.cpp
@@ -129,7 +129,6 @@ int main(int argc, char *argv[])
 		BaseLib::RunTime timer;
 		timer.start();
 		CS_read(in, n, iA, jA, A);
-		timer.stop();
 		INFO("\t- took %e s", timer.elapsed());
 	} else {
 		ERR("error reading matrix from %s", fname_mat.c_str());
@@ -180,8 +179,6 @@ int main(int argc, char *argv[])
 	for (size_t k(0); k<n_mults; k++) {
 		mat.amux (1.0, x, y);
 	}
-	cpu_timer.stop();
-	run_timer.stop();
 
 	INFO("\t[MVM] - took %e sec cpu time, %e sec run time", cpu_timer.elapsed(), run_timer.elapsed());
 
diff --git a/SimpleTests/MatrixTests/MatTestRemoveRowsCols.cpp b/SimpleTests/MatrixTests/MatTestRemoveRowsCols.cpp
index ce4b7e5f799ffc2ff65bee6f5745aeabbf664486..e2d390bc5b53661d27331baf4628bfa956d9e2cc 100644
--- a/SimpleTests/MatrixTests/MatTestRemoveRowsCols.cpp
+++ b/SimpleTests/MatrixTests/MatTestRemoveRowsCols.cpp
@@ -43,7 +43,6 @@ int main(int argc, char *argv[])
 		timer.start();
 		CS_read(in, n, iA, jA, A);
 		in.close();
-		timer.stop();
 		if (verbose) {
 			std::cout << "ok, " << timer.elapsed() << " s" << std::endl;
 		}
@@ -68,7 +67,6 @@ int main(int argc, char *argv[])
 	std::cout << "erasing " << n_rows_cols_to_erase << " rows and columns ... " << std::flush;
 	timer.start();
 	mat->eraseEntries(n_rows_cols_to_erase, rows_cols_to_erase);
-	timer.stop();
 	std::cout << "ok, " << timer.elapsed() << " s" << std::endl;
 	delete[] rows_cols_to_erase;
 
diff --git a/SimpleTests/MatrixTests/MatVecMultNDPerm.cpp b/SimpleTests/MatrixTests/MatVecMultNDPerm.cpp
index 7960ecef89e98336ab1a212ddcd4db79cb2beb54..0048e5a61bc33bf41bc9f558acecab68fa1bec09 100644
--- a/SimpleTests/MatrixTests/MatVecMultNDPerm.cpp
+++ b/SimpleTests/MatrixTests/MatVecMultNDPerm.cpp
@@ -119,7 +119,6 @@ int main(int argc, char *argv[])
 		BaseLib::RunTime timer;
 		timer.start();
 		CS_read(in, n, iA, jA, A);
-		timer.stop();
 		if (verbose) {
 			INFO("\t- took %e s", timer.elapsed());
 		}
@@ -156,8 +155,6 @@ int main(int argc, char *argv[])
 	for (unsigned k(0); k<n; k++)
 		op_perm[k] = po_perm[k] = k;
 	cluster_tree.createClusterTree(op_perm, po_perm, 1000);
-	cpu_timer.stop();
-	run_timer.stop();
 	if (verbose) {
 		INFO("\t[ND] - took %e sec \t%e sec", cpu_timer.elapsed(), run_timer.elapsed());
 	}
@@ -169,8 +166,6 @@ int main(int argc, char *argv[])
 	run_timer.start();
 	cpu_timer.start();
 	mat.reorderMatrix(op_perm, po_perm);
-	cpu_timer.stop();
-	run_timer.stop();
 	if (verbose) {
 		INFO("\t[ND]: - took %e sec\t%e sec", cpu_timer.elapsed(), run_timer.elapsed());
 	}
@@ -193,8 +188,6 @@ int main(int argc, char *argv[])
 	for (size_t k(0); k<n_mults; k++) {
 		mat.amux (1.0, x, y);
 	}
-	cpu_timer.stop();
-	run_timer.stop();
 
 	if (verbose) {
 		INFO("\t[MVM] - took %e sec\t %e sec", cpu_timer.elapsed(), run_timer.elapsed());
diff --git a/SimpleTests/MatrixTests/MatVecMultNDPermOpenMP.cpp b/SimpleTests/MatrixTests/MatVecMultNDPermOpenMP.cpp
index c39749b306ed7e8f568706e63e3eda534923077c..c43d0db2eafd8bb1be2d33efbf11813965f3e719 100644
--- a/SimpleTests/MatrixTests/MatVecMultNDPermOpenMP.cpp
+++ b/SimpleTests/MatrixTests/MatVecMultNDPermOpenMP.cpp
@@ -129,7 +129,6 @@ int main(int argc, char *argv[])
 		BaseLib::RunTime timer;
 		timer.start();
 		CS_read(in, n, iA, jA, A);
-		timer.stop();
 		if (verbose) {
 			INFO("\t- took %e s", timer.elapsed());
 		}
@@ -174,8 +173,6 @@ int main(int argc, char *argv[])
 	for (unsigned k(0); k<n; k++)
 		op_perm[k] = po_perm[k] = k;
 	cluster_tree.createClusterTree(op_perm, po_perm, 1000);
-	cpu_timer.stop();
-	run_timer.stop();
 	if (verbose) {
 		INFO("\t[ND] - took %e sec \t%e sec", cpu_timer.elapsed(), run_timer.elapsed());
 	}
@@ -187,8 +184,6 @@ int main(int argc, char *argv[])
 	run_timer.start();
 	cpu_timer.start();
 	mat.reorderMatrix(op_perm, po_perm);
-	cpu_timer.stop();
-	run_timer.stop();
 	if (verbose) {
 		INFO("\t[ND]: - took %e sec\t%e sec", cpu_timer.elapsed(), run_timer.elapsed());
 	}
@@ -202,8 +197,6 @@ int main(int argc, char *argv[])
 	for (size_t k(0); k<n_mults; k++) {
 		mat.amux (1.0, x, y);
 	}
-	cpu_timer.stop();
-	run_timer.stop();
 
 	if (verbose) {
 		INFO("\t[MVM] - took %e sec cpu time, %e sec run time", cpu_timer.elapsed(), run_timer.elapsed());
diff --git a/SimpleTests/MatrixTests/MatVecMultPthreads.cpp b/SimpleTests/MatrixTests/MatVecMultPthreads.cpp
index 0e12939701032289d858222bbf91b04b8affc044..31dca4130886c0ed6dc6945c4c5e5287b64cb97a 100644
--- a/SimpleTests/MatrixTests/MatVecMultPthreads.cpp
+++ b/SimpleTests/MatrixTests/MatVecMultPthreads.cpp
@@ -121,7 +121,6 @@ INFO("%s was build with compiler %s",
 		BaseLib::RunTime timer;
 		timer.start();
 		CS_read(in, n, iA, jA, A);
-		timer.stop();
 		INFO("\t- took %e s", timer.elapsed());
 	} else {
 		ERR("error reading matrix from %s", fname_mat.c_str());
@@ -151,8 +150,6 @@ INFO("%s was build with compiler %s",
 	for (size_t k(0); k<n_mults; k++) {
 		mat.amux (1.0, x, y);
 	}
-	cpu_timer.stop();
-	run_timer.stop();
 
 	INFO("\t[MVM] - took %e sec cpu time, %e sec run time", cpu_timer.elapsed(), run_timer.elapsed());
 
diff --git a/SimpleTests/MeshTests/MeshRead.cpp b/SimpleTests/MeshTests/MeshRead.cpp
index c07f045cde49d50af852b4fbce9c06803c5f6efe..d5067e6ddf20365d43fd53a94379ede55b4755cb 100644
--- a/SimpleTests/MeshTests/MeshRead.cpp
+++ b/SimpleTests/MeshTests/MeshRead.cpp
@@ -66,7 +66,7 @@ int main(int argc, char *argv[])
 //	std::cout << "mem for mesh: " << (mem_with_mesh - mem_without_mesh)/(1024*1024) << " MB" << std::endl;
 	INFO ("mem for mesh: %i MB", (mem_with_mesh - mem_without_mesh)/(1024*1024));
 #endif
-	run_time.stop();
+
 //	std::cout << "time for reading: " << run_time.elapsed() << " s" << std::endl;
 	INFO ("time for reading: %f s", run_time.elapsed());
 
diff --git a/SimpleTests/MeshTests/MeshSearchTest.cpp b/SimpleTests/MeshTests/MeshSearchTest.cpp
index ff299ccac7324b939a118921c94df03ef21443d2..9e78dfd3c1eadda1df45e30b1b4275a9a6e59d79 100644
--- a/SimpleTests/MeshTests/MeshSearchTest.cpp
+++ b/SimpleTests/MeshTests/MeshSearchTest.cpp
@@ -131,7 +131,6 @@ int main(int argc, char *argv[])
 	unsigned long mem_with_mesh (mem_watch.getVirtMemUsage());
 	INFO ("mem for mesh: %i MB", (mem_with_mesh - mem_without_mesh)/(1024*1024));
 #endif
-	run_time.stop();
 	INFO ("time for reading: %f s", run_time.elapsed());
 
 	// *** preparing test data
diff --git a/SimpleTests/SolverTests/BiCGStabDiagPrecond.cpp b/SimpleTests/SolverTests/BiCGStabDiagPrecond.cpp
index 7946ec31de21f25c6f87f9d647299921e4b5c5f3..621a3060a15b1d31e9fa5020f105e1bd61af7aa1 100644
--- a/SimpleTests/SolverTests/BiCGStabDiagPrecond.cpp
+++ b/SimpleTests/SolverTests/BiCGStabDiagPrecond.cpp
@@ -66,9 +66,6 @@ int main(int argc, char *argv[])
 
 	MathLib::BiCGStab ((*mat), b, x, eps, steps);
 
-	cpu_timer.stop();
-	run_timer.stop();
-
 	if (verbose) {
 		std::cout << " in " << steps << " iterations" << std::endl;
 		std::cout << "\t(residuum is " << eps << ") took " << cpu_timer.elapsed() << " sec time and " << run_timer.elapsed() << " sec" << std::endl;
diff --git a/SimpleTests/SolverTests/ConjugateGradientDiagonalPreconditioned.cpp b/SimpleTests/SolverTests/ConjugateGradientDiagonalPreconditioned.cpp
index a79fe47c0f0f3de330e0f760d8bc9ae226869c16..35e08af798394ff92a5ba3136698e7e8a3992e14 100644
--- a/SimpleTests/SolverTests/ConjugateGradientDiagonalPreconditioned.cpp
+++ b/SimpleTests/SolverTests/ConjugateGradientDiagonalPreconditioned.cpp
@@ -74,9 +74,6 @@ int main(int argc, char *argv[])
 		#endif
 	}
 
-	cpu_timer.stop();
-	run_timer.stop();
-
 	if (verbose) {
 		std::cout << " in " << steps << " iterations" << std::endl;
 		std::cout << "\t(residuum is " << eps << ") took " << cpu_timer.elapsed() << " sec time and " << run_timer.elapsed() << " sec" << std::endl;
diff --git a/SimpleTests/SolverTests/GMResDiagPrecond.cpp b/SimpleTests/SolverTests/GMResDiagPrecond.cpp
index ad742b913794b47b598db4657d7a872554bf4f6d..a7ceb91d5939ef7a92ffd872f6cc81ee541bca9c 100644
--- a/SimpleTests/SolverTests/GMResDiagPrecond.cpp
+++ b/SimpleTests/SolverTests/GMResDiagPrecond.cpp
@@ -70,9 +70,6 @@ int main(int argc, char *argv[])
 
 	MathLib::GMRes((*mat), b, x, eps, 30, steps);
 
-	cpu_timer.stop();
-	run_timer.stop();
-
 	if (verbose) {
 		std::cout << " in " << steps << " iterations" << std::endl;
 		std::cout << "\t(residuum is " << eps << ") took "