diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp
index 9fc6d68bb0ae5295925cb6bcefce8308cbbf5cf2..4e6e873478e84299787aef9b4a2644af8406093b 100644
--- a/src/language/modules/SchemeModule.cpp
+++ b/src/language/modules/SchemeModule.cpp
@@ -590,13 +590,23 @@ SchemeModule::SchemeModule()
                                                  }
 
                                                  ));
-  this->_addBuiltinFunction("fluxing_advection", std::function(
-
-                                                   [](const std::shared_ptr<const IMesh> new_mesh,
-                                                      const std::shared_ptr<const DiscreteFunctionVariant>& old_q)
-                                                     -> std::shared_ptr<const DiscreteFunctionVariant> {
-                                                     return FluxingAdvectionSolverHandler(new_mesh, old_q);
-                                                   }));
+  this
+    ->_addBuiltinFunction("fluxing_advection",
+                          std::function(
+
+                            // [](const std::shared_ptr<const IMesh> new_mesh,
+                            //    const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& remapped_variables)
+                            //   -> std::vector<std::shared_ptr<const DiscreteFunctionVariant>> {
+                            //   return FluxingAdvectionSolverHandler(new_mesh, remapped_variables);
+                            // }
+
+                            [](const std::shared_ptr<const IMesh> new_mesh,
+                               const std::shared_ptr<const DiscreteFunctionVariant>& remapped_variables)
+                              -> std::shared_ptr<const DiscreteFunctionVariant> {
+                              return FluxingAdvectionSolverHandler(new_mesh, remapped_variables);
+                            }
+
+                            ));
 
   MathFunctionRegisterForVh{*this};
 }
diff --git a/src/scheme/FluxingAdvectionSolver.cpp b/src/scheme/FluxingAdvectionSolver.cpp
index d3fcd4bb165e4c2b02c88157f97234e605eaf4a6..7ac8e85f21026ff9c6f83b26d5b949d7590972e8 100644
--- a/src/scheme/FluxingAdvectionSolver.cpp
+++ b/src/scheme/FluxingAdvectionSolver.cpp
@@ -4,21 +4,24 @@
 #include <mesh/Connectivity.hpp>
 #include <mesh/IMesh.hpp>
 #include <mesh/Mesh.hpp>
+#include <mesh/MeshData.hpp>
+#include <mesh/MeshDataManager.hpp>
+#include <mesh/MeshFaceBoundary.hpp>
+#include <mesh/SubItemValuePerItem.hpp>
 #include <scheme/DiscreteFunctionP0.hpp>
 #include <scheme/DiscreteFunctionUtils.hpp>
 #include <scheme/IDiscreteFunctionDescriptor.hpp>
-
 template <size_t Dimension>
 class FluxingAdvectionSolver
 {
  private:
   using Rd = TinyVector<Dimension>;
 
-  using MeshType = Mesh<Connectivity<Dimension>>;
+  using MeshType     = Mesh<Connectivity<Dimension>>;
+  using MeshDataType = MeshData<Dimension>;
 
   const std::shared_ptr<const MeshType> m_old_mesh;
   const std::shared_ptr<const MeshType> m_new_mesh;
-  const DiscreteFunctionP0<Dimension, const double> m_old_q;
 
  public:
   // CellValue<double>
@@ -72,32 +75,90 @@ class FluxingAdvectionSolver
   //   return Fnp1;
   // }
 
-  DiscreteFunctionP0<Dimension, double>
-  apply()
-  {
-    DiscreteFunctionP0<Dimension, double> new_q(m_new_mesh);
-    if (m_new_mesh->shared_connectivity() != m_old_mesh->shared_connectivity()) {
-      throw NormalError("Old and new meshes must share the same connectivity");
-    }
-    return new_q;
-  }
+  FaceValue<double> computeFluxVolume() const;
 
-  FluxingAdvectionSolver(const std::shared_ptr<const MeshType> old_mesh,
-                         const std::shared_ptr<const MeshType> new_mesh,
-                         const DiscreteFunctionP0<Dimension, const double>& old_q)
+  FluxingAdvectionSolver(const std::shared_ptr<const MeshType> old_mesh, const std::shared_ptr<const MeshType> new_mesh)
     : m_old_mesh{old_mesh}, m_new_mesh{new_mesh}
   {}
 
   ~FluxingAdvectionSolver() = default;
 };
 
-std::shared_ptr<const DiscreteFunctionVariant>
+template <>
+FaceValue<double>
+FluxingAdvectionSolver<1>::computeFluxVolume() const
+{
+  throw NotImplementedError("Viens");
+}
+
+template <>
+FaceValue<double>
+FluxingAdvectionSolver<2>::computeFluxVolume() const
+{
+  if (m_new_mesh->shared_connectivity() != m_old_mesh->shared_connectivity()) {
+    throw NormalError("Old and new meshes must share the same connectivity");
+  }
+  MeshDataType& old_mesh_data    = MeshDataManager::instance().getMeshData(*m_old_mesh);
+  MeshDataType& new_mesh_data    = MeshDataManager::instance().getMeshData(*m_new_mesh);
+  const auto face_to_node_matrix = m_old_mesh->connectivity().faceToNodeMatrix();
+  FaceValue<double> flux_volume(m_new_mesh->connectivity());
+  parallel_for(
+    m_new_mesh->numberOfFaces(), PUGS_LAMBDA(FaceId face_id) {
+      const auto face_to_node = face_to_node_matrix[face_id];
+      const Rd x0             = m_old_mesh->xr()[face_to_node[0]];
+      const Rd x1             = m_old_mesh->xr()[face_to_node[1]];
+      const Rd x2             = m_new_mesh->xr()[face_to_node[1]];
+      const Rd x3             = m_new_mesh->xr()[face_to_node[0]];
+      TinyMatrix<2> M(x2[0] - x0[0], x3[0] - x1[0], x2[1] - x0[1], x3[1] - x1[1]);
+      flux_volume[face_id] = 0.5 * det(M);
+    });
+  return flux_volume;
+}
+
+template <>
+FaceValue<double>
+FluxingAdvectionSolver<3>::computeFluxVolume() const
+{
+  throw NotImplementedError("ViensViensViens");
+}
+
+template <typename MeshType, typename DataType>
+auto
+remapUsingFluxing(const std::shared_ptr<const MeshType>& new_mesh,
+                  [[maybe_unused]] const FaceValue<double>& fluxing_volumes,
+                  const DiscreteFunctionP0<MeshType::Dimension, const DataType>& old_q)
+{
+  constexpr size_t Dimension = MeshType::Dimension;
+  //  const Connectivity<Dimension>& connectivity = new_mesh->connectivity();
+
+  DiscreteFunctionP0<Dimension, DataType> new_q(new_mesh, copy(old_q.cellValues()));
+
+  return new_q;
+}
+
+template <typename MeshType>
+auto
+remapUsingFluxing(const std::shared_ptr<const MeshType>& new_mesh,
+                  [[maybe_unused]] const FaceValue<double>& fluxing_volumes,
+                  const DiscreteFunctionP0Vector<MeshType::Dimension, const double>& old_q)
+{
+  constexpr size_t Dimension = MeshType::Dimension;
+  //  const Connectivity<Dimension>& connectivity = new_mesh->connectivity();
+
+  DiscreteFunctionP0Vector<Dimension, double> new_q(new_mesh, copy(old_q.cellArrays()));
+
+  throw NotImplementedError("DiscreteFunctionP0Vector");
+
+  return new_q;
+}
+
+std::vector<std::shared_ptr<const DiscreteFunctionVariant>>
 FluxingAdvectionSolverHandler(const std::shared_ptr<const IMesh> new_mesh,
-                              const std::shared_ptr<const DiscreteFunctionVariant>& old_q_v)
+                              const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& remapped_variables)
 {
-  const std::shared_ptr<const IMesh> old_mesh = getCommonMesh({old_q_v});
+  const std::shared_ptr<const IMesh> old_mesh = getCommonMesh(remapped_variables);
 
-  if (not checkDiscretizationType({old_q_v}, DiscreteFunctionType::P0)) {
+  if (not checkDiscretizationType({remapped_variables}, DiscreteFunctionType::P0)) {
     throw NormalError("acoustic solver expects P0 functions");
   }
 
@@ -108,17 +169,116 @@ FluxingAdvectionSolverHandler(const std::shared_ptr<const IMesh> new_mesh,
 
     const std::shared_ptr<const MeshType> old_mesh0 = std::dynamic_pointer_cast<const MeshType>(old_mesh);
 
-    const DiscreteFunctionP0<Dimension, const double>& old_q =
-      old_q_v->get<DiscreteFunctionP0<Dimension, const double>>();
+    const std::shared_ptr<const MeshType> new_mesh0 = std::dynamic_pointer_cast<const MeshType>(new_mesh);
+
+    FluxingAdvectionSolver<Dimension> solver(old_mesh0, new_mesh0);
+
+    FaceValue<double> fluxing_volumes(new_mesh0->connectivity());
+    fluxing_volumes.fill(0);
+
+    std::vector<std::shared_ptr<const DiscreteFunctionVariant>> new_variables;
+
+    // for (auto&& variable_v : remapped_variables) {
+    //   std::visit(
+    //     [&](auto&& variable) {
+    //       using DiscreteFunctionT = std::decay_t<decltype(variable)>;
+    //       if constexpr (std::is_same_v<MeshType, typename DiscreteFunctionT::MeshType>) {
+    //         remapUsingFluxing(new_mesh0, fluxing_volumes, variable);
+    //       }
+    //     },
+    //     variable_v->discreteFunction());
+    // }
+
+    return remapped_variables;   // std::make_shared<std::vector<std::shared_ptr<const
+                                 // DiscreteFunctionVariant>>>(new_variables);
+  }
+  case 2: {
+    constexpr size_t Dimension = 2;
+
+    using MeshType = Mesh<Connectivity<Dimension>>;
+
+    const std::shared_ptr<const MeshType> old_mesh0 = std::dynamic_pointer_cast<const MeshType>(old_mesh);
+
+    const std::shared_ptr<const MeshType> new_mesh0 = std::dynamic_pointer_cast<const MeshType>(new_mesh);
+
+    FluxingAdvectionSolver<Dimension> solver(old_mesh0, new_mesh0);
+
+    FaceValue<double> fluxing_volumes(new_mesh0->connectivity());
+    fluxing_volumes.fill(0);
+
+    std::vector<std::shared_ptr<const DiscreteFunctionVariant>> new_variables;
+
+    // for (auto&& variable_v : remapped_variables) {
+    //   std::visit(
+    //     [&](auto&& variable) {
+    //       using DiscreteFunctionT = std::decay_t<decltype(variable)>;
+    //       if constexpr (std::is_same_v<MeshType, typename DiscreteFunctionT::MeshType>) {
+    //         remapUsingFluxing(new_mesh0, fluxing_volumes, variable);
+    //       }
+    //     },
+    //     variable_v->discreteFunction());
+    // }
+
+    return remapped_variables;   // std::make_shared<std::vector<std::shared_ptr<const
+
+    // throw NotImplementedError("Fluxing advection solver not implemented in dimension 2");
+  }
+  case 3: {
+    throw NotImplementedError("Fluxing advection solver not implemented in dimension 3");
+  }
+  default: {
+    throw UnexpectedError("Invalid mesh dimension");
+  }
+  }
+}
+
+std::shared_ptr<const DiscreteFunctionVariant>
+FluxingAdvectionSolverHandler(const std::shared_ptr<const IMesh> new_mesh,
+                              const std::shared_ptr<const DiscreteFunctionVariant>& remapped_variables)
+{
+  const std::shared_ptr<const IMesh> old_mesh = getCommonMesh({remapped_variables});
+
+  if (not checkDiscretizationType({remapped_variables}, DiscreteFunctionType::P0)) {
+    throw NormalError("acoustic solver expects P0 functions");
+  }
+
+  switch (old_mesh->dimension()) {
+  case 1: {
+    constexpr size_t Dimension = 1;
+    using MeshType             = Mesh<Connectivity<Dimension>>;
+
+    const std::shared_ptr<const MeshType> old_mesh0 = std::dynamic_pointer_cast<const MeshType>(old_mesh);
 
     const std::shared_ptr<const MeshType> new_mesh0 = std::dynamic_pointer_cast<const MeshType>(new_mesh);
 
-    FluxingAdvectionSolver<Dimension> solver(old_mesh0, new_mesh0, old_q);
+    // FluxingAdvectionSolver<Dimension> solver(old_mesh0, new_mesh0);
+
+    FaceValue<double> fluxing_volumes(old_mesh0->connectivity());
+    fluxing_volumes.fill(0);
 
-    return std::make_shared<DiscreteFunctionVariant>(solver.apply());
+    return std::make_shared<DiscreteFunctionVariant>(
+      remapUsingFluxing(new_mesh0, fluxing_volumes,
+                        remapped_variables->get<DiscreteFunctionP0<Dimension, const double>>()));
   }
   case 2: {
-    throw NotImplementedError("Fluxing advection solver not implemented in dimension 2");
+    constexpr size_t Dimension = 2;
+    using MeshType             = Mesh<Connectivity<Dimension>>;
+
+    const std::shared_ptr<const MeshType> old_mesh0 = std::dynamic_pointer_cast<const MeshType>(old_mesh);
+
+    const std::shared_ptr<const MeshType> new_mesh0 = std::dynamic_pointer_cast<const MeshType>(new_mesh);
+
+    FluxingAdvectionSolver<Dimension> solver(old_mesh0, new_mesh0);
+
+    FaceValue<double> fluxing_volumes = solver.computeFluxVolume();
+    //(new_mesh0->connectivity());
+    // fluxing_volumes.fill(0);
+
+    return std::make_shared<DiscreteFunctionVariant>(
+      remapUsingFluxing(new_mesh0, fluxing_volumes,
+                        remapped_variables->get<DiscreteFunctionP0<Dimension, const double>>()));
+
+    // throw NotImplementedError("Fluxing advection solver not implemented in dimension 2");
   }
   case 3: {
     throw NotImplementedError("Fluxing advection solver not implemented in dimension 3");
diff --git a/src/scheme/FluxingAdvectionSolver.hpp b/src/scheme/FluxingAdvectionSolver.hpp
index d51ebb303a652d544419a1904c50785bf025c14c..43a3e6424432d6fc79a7cfcdbe9907a2130a8ee1 100644
--- a/src/scheme/FluxingAdvectionSolver.hpp
+++ b/src/scheme/FluxingAdvectionSolver.hpp
@@ -4,8 +4,14 @@
 #include <language/utils/FunctionSymbolId.hpp>
 #include <scheme/DiscreteFunctionVariant.hpp>
 
+#include <vector>
+
+std::vector<std::shared_ptr<const DiscreteFunctionVariant>> FluxingAdvectionSolverHandler(
+  const std::shared_ptr<const IMesh> new_mesh,
+  const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& remapped_variables);
+
 std::shared_ptr<const DiscreteFunctionVariant> FluxingAdvectionSolverHandler(
   const std::shared_ptr<const IMesh> new_mesh,
-  const std::shared_ptr<const DiscreteFunctionVariant>& old_q);
+  const std::shared_ptr<const DiscreteFunctionVariant>& remapped_variables);
 
 #endif   // FLUXING_ADVECION_SOLVER_HPP