diff --git a/src/scheme/EulerKineticSolverLagrangeMultiD.cpp b/src/scheme/EulerKineticSolverLagrangeMultiD.cpp
index 70423dfc07916d6f20cec371604b3bd53e1b37f4..3e8eb0b8a170b63565ea9a377745e65f6c255fd0 100644
--- a/src/scheme/EulerKineticSolverLagrangeMultiD.cpp
+++ b/src/scheme/EulerKineticSolverLagrangeMultiD.cpp
@@ -251,6 +251,241 @@ class EulerKineticSolverLagrangeMultiD
     return Fr;
   }
 
+  void
+  apply_bc(NodeArray<double>& Fr_p,
+           NodeArray<TinyVector<Dimension>>& Fr_u,
+           const CellValue<const double>& p,
+           const CellValue<const TinyVector<Dimension>>& u,
+           const CellArray<const double>& Fn_p,
+           const CellArray<const TinyVector<Dimension>>& Fn_u,
+           const double& lambda,
+           const BoundaryConditionList& bc_list)
+  {
+    const size_t nb_waves                                   = m_lambda_vector.size();
+    const auto& node_local_numbers_in_their_cells           = p_mesh->connectivity().nodeLocalNumbersInTheirCells();
+    const auto& node_to_cell_matrix                         = p_mesh->connectivity().nodeToCellMatrix();
+    const NodeValuePerCell<const TinyVector<Dimension>> njr = MeshDataManager::instance().getMeshData(m_mesh).njr();
+    const NodeValuePerCell<const TinyVector<Dimension>> Cjr = MeshDataManager::instance().getMeshData(m_mesh).Cjr();
+
+    TinyVector<MeshType::Dimension> inv_S = zero;
+    for (size_t d = 0; d < MeshType::Dimension; ++d) {
+      for (size_t i = 0; i < nb_waves; ++i) {
+        inv_S[d] += m_lambda_vector[i][d] * m_lambda_vector[i][d];
+      }
+      inv_S[d] = 1. / inv_S[d];
+    }
+
+    for (auto&& bc_v : bc_list) {
+      std::visit(
+        [=, this](auto&& bc) {
+          using BCType = std::decay_t<decltype(bc)>;
+          if constexpr (std::is_same_v<BCType, SymmetryBoundaryCondition>) {
+            auto node_list = bc.nodeList();
+
+            TinyMatrix<Dimension> I = identity;
+
+            NodeValue<TinyVector<Dimension>> nr{p_mesh->connectivity()};
+            nr.fill(zero);
+
+            for (size_t i_node = 0; i_node < node_list.size(); ++i_node) {
+              const NodeId node_id                      = node_list[i_node];
+              const auto& node_to_cell                  = node_to_cell_matrix[node_id];
+              const auto& node_local_number_in_its_cell = node_local_numbers_in_their_cells.itemArray(node_id);
+              for (size_t i_cell = 0; i_cell < node_to_cell.size(); ++i_cell) {
+                const CellId cell_id     = node_to_cell[i_cell];
+                const size_t i_node_cell = node_local_number_in_its_cell[i_cell];
+
+                nr[node_id] += Cjr(cell_id, i_node_cell);
+              }
+              nr[node_id] = 1. / sqrt(dot(nr[node_id], nr[node_id])) * nr[node_id];
+              auto nxn    = tensorProduct(nr[node_id], nr[node_id]);
+              auto txt    = I - nxn;
+
+              for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) {
+                double sum            = 0;
+                Fr_p[node_id][i_wave] = 0;
+                Fr_u[node_id][i_wave] = zero;
+
+                for (size_t i_cell = 0; i_cell < node_to_cell.size(); ++i_cell) {
+                  const CellId cell_id     = node_to_cell[i_cell];
+                  const size_t i_node_cell = node_local_number_in_its_cell[i_cell];
+
+                  double li_njr = dot(m_lambda_vector[i_wave], njr(cell_id, i_node_cell));
+
+                  if (li_njr > 1e-14) {
+                    Fr_p[node_id][i_wave] += Fn_p[cell_id][i_wave] * li_njr;
+                    Fr_u[node_id][i_wave] += li_njr * Fn_u[cell_id][i_wave];
+
+                    sum += li_njr;
+                  }
+
+                  TinyVector<Dimension> njr_prime = txt * njr(cell_id, i_node_cell) - nxn * njr(cell_id, i_node_cell);
+                  double li_njr_prime             = dot(m_lambda_vector[i_wave], njr_prime);
+
+                  if (li_njr_prime > 1e-14) {
+                    double p_prime                = p[cell_id];
+                    TinyVector<Dimension> u_prime = txt * u[cell_id] - nxn * u[cell_id];
+
+                    TinyVector<Dimension> A_p_prime = lambda * lambda * u_prime;
+                    TinyMatrix<Dimension> A_u_prime = p_prime * I;
+
+                    double Fn_p_prime                = p_prime / nb_waves;
+                    TinyVector<Dimension> Fn_u_prime = 1. / nb_waves * u_prime;
+
+                    for (size_t d1 = 0; d1 < Dimension; ++d1) {
+                      Fn_p_prime += inv_S[d1] * m_lambda_vector[i_wave][d1] * A_p_prime[d1];
+                      for (size_t d2 = 0; d2 < Dimension; ++d2) {
+                        Fn_u_prime[d1] += inv_S[d2] * m_lambda_vector[i_wave][d2] * A_u_prime(d2, d1);
+                      }
+                    }
+
+                    Fr_p[node_id][i_wave] += Fn_p_prime * li_njr_prime;
+                    Fr_u[node_id][i_wave] += li_njr_prime * Fn_u_prime;
+
+                    sum += li_njr_prime;
+                  }
+                }
+                if (sum != 0) {
+                  Fr_p[node_id][i_wave] /= sum;
+                  Fr_u[node_id][i_wave] = 1. / sum * Fr_u[node_id][i_wave];
+                }
+              }
+            }
+          } else if constexpr (std::is_same_v<BCType, WallBoundaryCondition>) {
+            auto node_list = bc.nodeList();
+
+            TinyMatrix<Dimension> I = identity;
+
+            NodeValue<TinyVector<Dimension>> nr{p_mesh->connectivity()};
+            nr.fill(zero);
+
+            for (size_t i_node = 0; i_node < node_list.size(); ++i_node) {
+              const NodeId node_id                      = node_list[i_node];
+              const auto& node_to_cell                  = node_to_cell_matrix[node_id];
+              const auto& node_local_number_in_its_cell = node_local_numbers_in_their_cells.itemArray(node_id);
+
+              for (size_t i_cell = 0; i_cell < node_to_cell.size(); ++i_cell) {
+                const CellId cell_id     = node_to_cell[i_cell];
+                const size_t i_node_cell = node_local_number_in_its_cell[i_cell];
+
+                nr[node_id] += Cjr(cell_id, i_node_cell);
+              }
+              nr[node_id] = 1. / sqrt(dot(nr[node_id], nr[node_id])) * nr[node_id];
+              auto nxn    = tensorProduct(nr[node_id], nr[node_id]);
+              auto txt    = I - nxn;
+
+              for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) {
+                double sum            = 0;
+                Fr_p[node_id][i_wave] = 0;
+                Fr_u[node_id][i_wave] = zero;
+
+                for (size_t i_cell = 0; i_cell < node_to_cell.size(); ++i_cell) {
+                  const CellId cell_id     = node_to_cell[i_cell];
+                  const size_t i_node_cell = node_local_number_in_its_cell[i_cell];
+
+                  double li_njr = dot(m_lambda_vector[i_wave], njr(cell_id, i_node_cell));
+
+                  if (li_njr > 1e-14) {
+                    Fr_p[node_id][i_wave] += Fn_p[cell_id][i_wave] * li_njr;
+                    Fr_u[node_id][i_wave] += li_njr * Fn_u[cell_id][i_wave];
+
+                    sum += li_njr;
+                  }
+
+                  TinyVector<Dimension> njr_prime = txt * njr(cell_id, i_node_cell) - nxn * njr(cell_id, i_node_cell);
+                  double li_njr_prime             = dot(m_lambda_vector[i_wave], njr_prime);
+
+                  if (li_njr_prime > 1e-14) {
+                    double p_prime                = p[cell_id];
+                    TinyVector<Dimension> u_prime = txt * u[cell_id] - nxn * u[cell_id];
+
+                    TinyVector<Dimension> A_p_prime = lambda * lambda * u_prime;
+                    TinyMatrix<Dimension> A_u_prime = p_prime * I;
+
+                    double Fn_p_prime                = p_prime / nb_waves;
+                    TinyVector<Dimension> Fn_u_prime = 1. / nb_waves * u_prime;
+
+                    for (size_t d1 = 0; d1 < Dimension; ++d1) {
+                      Fn_p_prime += inv_S[d1] * m_lambda_vector[i_wave][d1] * A_p_prime[d1];
+                      for (size_t d2 = 0; d2 < Dimension; ++d2) {
+                        Fn_u_prime[d1] += inv_S[d2] * m_lambda_vector[i_wave][d2] * A_u_prime(d2, d1);
+                      }
+                    }
+
+                    Fr_p[node_id][i_wave] += Fn_p_prime * li_njr_prime;
+                    Fr_u[node_id][i_wave] += li_njr_prime * Fn_u_prime;
+
+                    sum += li_njr_prime;
+                  }
+                }
+                if (sum != 0) {
+                  Fr_p[node_id][i_wave] /= sum;
+                  Fr_u[node_id][i_wave] = 1. / sum * Fr_u[node_id][i_wave];
+                }
+              }
+            }
+          } else if constexpr (std::is_same_v<BCType, OutflowBoundaryCondition>) {
+            auto node_list          = bc.nodeList();
+            TinyMatrix<Dimension> I = identity;
+
+            NodeValue<TinyVector<Dimension>> nr{p_mesh->connectivity()};
+            nr.fill(zero);
+
+            for (size_t i_node = 0; i_node < node_list.size(); ++i_node) {
+              const NodeId node_id                      = node_list[i_node];
+              const auto& node_to_cell                  = node_to_cell_matrix[node_id];
+              const auto& node_local_number_in_its_cell = node_local_numbers_in_their_cells.itemArray(node_id);
+
+              for (size_t i_cell = 0; i_cell < node_to_cell.size(); ++i_cell) {
+                const CellId cell_id     = node_to_cell[i_cell];
+                const size_t i_node_cell = node_local_number_in_its_cell[i_cell];
+
+                nr[node_id] += Cjr(cell_id, i_node_cell);
+              }
+              nr[node_id] = 1. / sqrt(dot(nr[node_id], nr[node_id])) * nr[node_id];
+              auto nxn    = tensorProduct(nr[node_id], nr[node_id]);
+              auto txt    = I - nxn;
+
+              for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) {
+                double sum            = 0;
+                Fr_p[node_id][i_wave] = 0;
+                Fr_u[node_id][i_wave] = zero;
+
+                for (size_t i_cell = 0; i_cell < node_to_cell.size(); ++i_cell) {
+                  const CellId cell_id     = node_to_cell[i_cell];
+                  const size_t i_node_cell = node_local_number_in_its_cell[i_cell];
+
+                  double li_njr = dot(m_lambda_vector[i_wave], njr(cell_id, i_node_cell));
+
+                  if (li_njr > 1e-14) {
+                    Fr_p[node_id][i_wave] += Fn_p[cell_id][i_wave] * li_njr;
+                    Fr_u[node_id][i_wave] += li_njr * Fn_u[cell_id][i_wave];
+
+                    sum += li_njr;
+                  }
+
+                  TinyVector<Dimension> njr_prime = txt * njr(cell_id, i_node_cell) - nxn * njr(cell_id, i_node_cell);
+                  double li_njr_prime             = dot(m_lambda_vector[i_wave], njr_prime);
+
+                  if (li_njr_prime > 1e-14) {
+                    Fr_p[node_id][i_wave] += Fn_p[cell_id][i_wave] * li_njr_prime;
+                    Fr_u[node_id][i_wave] += li_njr_prime * Fn_u[cell_id][i_wave];
+
+                    sum += li_njr_prime;
+                  }
+                }
+                if (sum != 0) {
+                  Fr_p[node_id][i_wave] /= sum;
+                  Fr_u[node_id][i_wave] = 1. / sum * Fr_u[node_id][i_wave];
+                }
+              }
+            }
+          }
+        },
+        bc_v);
+    }
+  }
+
   const NodeValue<TinyVector<Dimension>>
   compute_velocity_flux(NodeArray<double>& F, const double& lambda)
   {
@@ -409,6 +644,8 @@ class EulerKineticSolverLagrangeMultiD
     NodeArray<double> Fr_p                = compute_Flux<double>(F_p, is_boundary_node);
     NodeArray<TinyVector<Dimension>> Fr_u = compute_Flux<TinyVector<Dimension>>(F_u, is_boundary_node);
 
+    apply_bc(Fr_p, Fr_u, p, u, F_p, F_u, lambda, bc_list);
+
     const NodeValue<TinyVector<Dimension>> ur = compute_velocity_flux(Fr_p, lambda);
     const NodeValue<TinyVector<Dimension>> pr = compute_pressure_flux(Fr_u);