diff --git a/ProcessLib/ComponentTransport/ComponentTransportProcess.cpp b/ProcessLib/ComponentTransport/ComponentTransportProcess.cpp
index 85d12f1cc0f472887b32e7118fbd72d406ca9af8..88022dfc0317bf6ffb72ba04761f8fe4f5c5179d 100644
--- a/ProcessLib/ComponentTransport/ComponentTransportProcess.cpp
+++ b/ProcessLib/ComponentTransport/ComponentTransportProcess.cpp
@@ -21,6 +21,7 @@
 #include "NumLib/DOF/ComputeSparsityPattern.h"
 #include "ProcessLib/SurfaceFlux/SurfaceFlux.h"
 #include "ProcessLib/SurfaceFlux/SurfaceFluxData.h"
+#include "ProcessLib/Utils/ComputeResiduum.h"
 #include "ProcessLib/Utils/CreateLocalAssemblers.h"
 
 namespace ProcessLib
@@ -48,9 +49,14 @@ ComponentTransportProcess::ComponentTransportProcess(
       _surfaceflux(std::move(surfaceflux)),
       _chemical_solver_interface(std::move(chemical_solver_interface))
 {
-    // Todo(renchao): Need to adapt for the multi-component case.
-    _molar_flow_rate = MeshLib::getOrCreateMeshProperty<double>(
-        mesh, "MolarFlowRate", MeshLib::MeshItemType::Node, 1);
+    std::size_t n_processes = _process_variables.size();
+    _molar_flow_rate.resize(n_processes - 1);
+    for (int process_id = 0; process_id < n_processes - 1; ++process_id)
+    {
+        _molar_flow_rate[process_id] = MeshLib::getOrCreateMeshProperty<double>(
+            mesh, "MolarFlowRate_" + std::to_string(process_id),
+            MeshLib::MeshItemType::Node, 1);
+    }
 }
 
 void ComponentTransportProcess::initializeConcreteProcess(
@@ -170,6 +176,15 @@ void ComponentTransportProcess::assembleConcreteProcess(
         _global_assembler, &VectorMatrixAssembler::assemble, _local_assemblers,
         pv.getActiveElementIDs(), dof_tables, t, dt, x, xdot, process_id, M, K,
         b);
+
+    MathLib::finalizeMatrixAssembly(M);
+    MathLib::finalizeMatrixAssembly(K);
+    MathLib::finalizeVectorAssembly(b);
+
+    auto const residuum = computeResiduum(*x[0], *xdot[0], M, K, b);
+    transformVariableFromGlobalVector(residuum, 0, *_local_to_global_index_map,
+                                      *_molar_flow_rate[process_id],
+                                      std::negate<double>());
 }
 
 void ComponentTransportProcess::assembleWithJacobianConcreteProcess(
@@ -201,9 +216,9 @@ void ComponentTransportProcess::assembleWithJacobianConcreteProcess(
 
     // b is the negated residumm used in the Newton's method.
     // Here negating b is to recover the primitive residuum.
-    transformVariableFromGlobalVector(b, 0 /*variable id*/,
-                                      *_local_to_global_index_map,
-                                      *_molar_flow_rate, std::negate<double>());
+    transformVariableFromGlobalVector(
+        b, process_id, *_local_to_global_index_map,
+        *_molar_flow_rate[process_id], std::negate<double>());
 }
 
 Eigen::Vector3d ComponentTransportProcess::getFlux(
diff --git a/ProcessLib/ComponentTransport/ComponentTransportProcess.h b/ProcessLib/ComponentTransport/ComponentTransportProcess.h
index 8c48ca410fbd6023a4e633e9530b633ea6b74390..da1ac9fb79b379ea1a17ae28ddbde00045907930 100644
--- a/ProcessLib/ComponentTransport/ComponentTransportProcess.h
+++ b/ProcessLib/ComponentTransport/ComponentTransportProcess.h
@@ -170,7 +170,7 @@ private:
     std::unique_ptr<ChemistryLib::ChemicalSolverInterface>
         _chemical_solver_interface;
 
-    MeshLib::PropertyVector<double>* _molar_flow_rate = nullptr;
+    std::vector<MeshLib::PropertyVector<double>*> _molar_flow_rate;
 };
 
 }  // namespace ComponentTransport