From bd7389e3e103c3d2a8fd91e0b3b78a34ec6ec569 Mon Sep 17 00:00:00 2001
From: Alexander Jaust <alexander.jaust@ipvs.uni-stuttgart.de>
Date: Thu, 23 May 2019 12:25:42 +0200
Subject: [PATCH] [ff-pm] mild integration of precice for ff-pm testcase; Need
 to integrate/reconstruct boundary values properly

---
 README.md                                     |   3 +-
 appl/coupling-ff-pm/CMakeLists.txt            |   1 +
 appl/coupling-ff-pm/iterative/CMakeLists.txt  |  29 ++-
 appl/coupling-ff-pm/iterative/main_ff.cc      | 116 ++++++++++-
 appl/coupling-ff-pm/iterative/main_pm.cc      | 185 +++++++++++++++---
 appl/coupling-ff-pm/monolithic/ffproblem.hh   |  35 +++-
 appl/coupling-ff-pm/monolithic/pmproblem.hh   |  16 +-
 .../docs/dumux_precice_coupling.md            |  23 +++
 8 files changed, 366 insertions(+), 42 deletions(-)

diff --git a/README.md b/README.md
index 9055d28..09f4d48 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
 # DuMuX-preCICE coupling 
 
+
 ## Prerequisites
 
 - DuMuX **newer** than 3.0
@@ -18,4 +19,4 @@ At the moment the following has to be fulfilled
 
 ## Further reading
 
-There is more documentation in `doc/mkdocs`.
\ No newline at end of file
+There is more documentation in `doc/mkdocs`.
diff --git a/appl/coupling-ff-pm/CMakeLists.txt b/appl/coupling-ff-pm/CMakeLists.txt
index fe2d97c..a2de49f 100644
--- a/appl/coupling-ff-pm/CMakeLists.txt
+++ b/appl/coupling-ff-pm/CMakeLists.txt
@@ -1,5 +1,6 @@
 # add a target that builds all exercise solutions
 add_custom_target(test_exercises)
 
+
 add_subdirectory(monolithic)
 add_subdirectory(iterative)
diff --git a/appl/coupling-ff-pm/iterative/CMakeLists.txt b/appl/coupling-ff-pm/iterative/CMakeLists.txt
index ff70d2b..bc25cc0 100644
--- a/appl/coupling-ff-pm/iterative/CMakeLists.txt
+++ b/appl/coupling-ff-pm/iterative/CMakeLists.txt
@@ -1,11 +1,28 @@
 # executables for the iterative case
-dune_add_test(NAME test_ff
-              SOURCES main_ff.cc
-              COMPILE_DEFINITIONS ENABLEMONOLITHIC=0)
+string(REPLACE ":" ";" LIBRARY_DIRS $ENV{LD_LIBRARY_PATH})
+find_library(PRECICE_LIB NAMES precice HINTS ${LIBRARY_DIRS})
+find_package(Boost 1.65.1 REQUIRED COMPONENTS log system) #Require same version as preCICE
 
-dune_add_test(NAME test_pm
-              SOURCES main_pm.cc
-              COMPILE_DEFINITIONS ENABLEMONOLITHIC=0)
+#dune_add_test(NAME test_ff
+#              SOURCES main_ff.cc ../precice/preciceadapter.cc ../precice/dumuxpreciceindexwrapper.cc
+#              COMPILE_DEFINITIONS ENABLEMONOLITHIC=0)
 
+#dune_add_test(NAME test_pm
+#              SOURCES main_pm.cc ../precice/preciceadapter.cc ../precice/dumuxpreciceindexwrapper.cc
+#              COMPILE_DEFINITIONS ENABLEMONOLITHIC=0)
+
+add_executable(test_ff EXCLUDE_FROM_ALL main_ff.cc ../precice/preciceadapter.cc ../precice/dumuxpreciceindexwrapper.cc)
+add_executable(test_pm EXCLUDE_FROM_ALL main_pm.cc ../precice/preciceadapter.cc ../precice/dumuxpreciceindexwrapper.cc)
+
+target_compile_definitions(test_ff PUBLIC "ENABLEMONOLITHIC=0")
+target_compile_definitions(test_pm PUBLIC "ENABLEMONOLITHIC=0")
+
+target_compile_definitions(test_ff PRIVATE BOOST_ALL_DYN_LINK)
+target_link_libraries(test_ff PRIVATE ${Boost_LIBRARIES} ${PRECICE_LIB})
+target_include_directories(test_ff PRIVATE ${Boost_INCLUDE_DIRS})
+
+target_compile_definitions(test_pm PRIVATE BOOST_ALL_DYN_LINK)
+target_link_libraries(test_pm PRIVATE ${Boost_LIBRARIES} ${PRECICE_LIB})
+target_include_directories(test_pm PRIVATE ${Boost_INCLUDE_DIRS})
 # add a symlink for each input file
 add_input_file_links()
diff --git a/appl/coupling-ff-pm/iterative/main_ff.cc b/appl/coupling-ff-pm/iterative/main_ff.cc
index f15f629..faee282 100644
--- a/appl/coupling-ff-pm/iterative/main_ff.cc
+++ b/appl/coupling-ff-pm/iterative/main_ff.cc
@@ -47,6 +47,11 @@
 
 #include "../monolithic/ffproblem.hh"
 
+#include "../precice/preciceadapter.hh"
+
+//TODO
+// Helper function to put pressure on interface
+
 int main(int argc, char** argv) try
 {
     using namespace Dumux;
@@ -86,6 +91,61 @@ int main(int argc, char** argv) try
     sol[FreeFlowFVGridGeometry::cellCenterIdx()].resize(freeFlowFvGridGeometry->numCellCenterDofs());
     sol[FreeFlowFVGridGeometry::faceIdx()].resize(freeFlowFvGridGeometry->numFaceDofs());
 
+    // Initialize preCICE.Tell preCICE about:
+    // - Name of solver
+    // - What rank of how many ranks this instance is
+    // Configure preCICE. For now the config file is hardcoded.
+    //couplingInterface.createInstance( "FreeFlow", mpiHelper.rank(), mpiHelper.size() );
+    std::string preciceConfigFilename = "precice-config.xml";
+    if (argc == 3)
+      preciceConfigFilename = argv[2];
+
+    auto& couplingInterface =
+        precice_adapter::PreciceAdapter::getInstance();
+    couplingInterface.announceSolver( "FreeFlow", preciceConfigFilename,
+                                      mpiHelper.rank(), mpiHelper.size() );
+
+    const auto velocityId = couplingInterface.announceQuantity( "Velocity" );
+    const auto pressureId = couplingInterface.announceQuantity( "Pressure" );
+
+    const int dim = couplingInterface.getDimensions();
+    std::cout << dim << "  " << int(FreeFlowFVGridGeometry::GridView::dimension) << std::endl;
+    if (dim != int(FreeFlowFVGridGeometry::GridView::dimension))
+        DUNE_THROW(Dune::InvalidStateException, "Dimensions do not match");
+
+    // GET mesh corodinates
+    const double xMin = getParamFromGroup<std::vector<double>>("Darcy", "Grid.Positions0")[0];
+    const double xMax = getParamFromGroup<std::vector<double>>("Darcy", "Grid.Positions0").back();
+    std::vector<double> coords; //( dim * vertexSize );
+    std::vector<int> coupledScvfIndices;
+
+    for (const auto& element : elements(freeFlowGridView))
+    {
+        auto fvGeometry = localView(*freeFlowFvGridGeometry);
+        fvGeometry.bindElement(element);
+
+        for (const auto& scvf : scvfs(fvGeometry))
+        {
+            static constexpr auto eps = 1e-7;
+            const auto& pos = scvf.center();
+            if (pos[1] < freeFlowFvGridGeometry->bBoxMin()[1] + eps)
+            {
+                if (pos[0] > xMin - eps && pos[0] < xMax + eps)
+                {
+                  coupledScvfIndices.push_back(scvf.index());
+                    for (const auto p : pos)
+                        coords.push_back(p);
+                }
+            }
+        }
+    }
+
+    const auto numberOfPoints = coords.size() / dim;
+    const double preciceDt = couplingInterface.setMeshAndInitialize( "FreeFlowMesh",
+                                                                     numberOfPoints,
+                                                                     coords,
+                                                                     coupledScvfIndices );
+
 
     // apply initial solution for instationary problems
     freeFlowProblem->applyInitialSolution(sol);
@@ -101,6 +161,15 @@ int main(int argc, char** argv) try
     freeFlowVtkWriter.addField(freeFlowProblem->getAnalyticalVelocityX(), "analyticalV_x");
     freeFlowVtkWriter.write(0.0);
 
+    if ( couplingInterface.hasToWriteInitialData() )
+    {
+      //TODO
+//      couplingInterface.writeQuantityVector( pressureId );
+      couplingInterface.writeQuantityToOtherSolver( pressureId );
+      couplingInterface.announceInitialDataWritten();
+    }
+    couplingInterface.initializeData();
+
     // the assembler for a stationary problem
     using Assembler = StaggeredFVAssembler<FreeFlowTypeTag, DiffMethod::numeric>;
     auto assembler = std::make_shared<Assembler>(freeFlowProblem, freeFlowFvGridGeometry, freeFlowGridVariables);
@@ -113,16 +182,55 @@ int main(int argc, char** argv) try
     using NewtonSolver = NewtonSolver<Assembler, LinearSolver>;
     NewtonSolver nonLinearSolver(assembler, linearSolver);
 
-    // solve the non-linear system
-    nonLinearSolver.solve(sol);
 
-    // write vtk output
-    freeFlowVtkWriter.write(1.0);
+    auto dt = preciceDt;
+    auto sol_checkpoint = sol;
+
+    while ( couplingInterface.isCouplingOngoing() )
+    {
+        if ( couplingInterface.hasToWriteIterationCheckpoint() )
+        {
+            //DO CHECKPOINTING
+            sol_checkpoint = sol;
+            couplingInterface.announceIterationCheckpointWritten();
+        }
+
+        // TODO
+        couplingInterface.readQuantityFromOtherSolver( velocityId );
+
+        // solve the non-linear system
+        nonLinearSolver.solve(sol);
+
+        // TODO
+        // FILL DATA vector
+        //      couplingInterface.writeQuantityVector( pressureId );
+        couplingInterface.writeQuantityToOtherSolver( pressureId );
+
+        const double preciceDt = couplingInterface.advance( dt );
+        dt = std::min( preciceDt, dt );
 
+        if ( couplingInterface.hasToReadIterationCheckpoint() )
+        {
+            //Read checkpoint
+            sol = sol_checkpoint;
+            //freeFlowGridVariables->update(sol);
+            //freeFlowGridVariables->advanceTimeStep();
+            freeFlowGridVariables->init(sol);
+            couplingInterface.announceIterationCheckpointRead();
+        }
+        else // coupling successful
+        {
+          // write vtk output
+          freeFlowVtkWriter.write(1.0);
+        }
+
+    }
     ////////////////////////////////////////////////////////////
     // finalize, print dumux message to say goodbye
     ////////////////////////////////////////////////////////////
 
+    couplingInterface.finalize();
+
     // print dumux end message
     if (mpiHelper.rank() == 0)
     {
diff --git a/appl/coupling-ff-pm/iterative/main_pm.cc b/appl/coupling-ff-pm/iterative/main_pm.cc
index fbdbb2c..6874f09 100644
--- a/appl/coupling-ff-pm/iterative/main_pm.cc
+++ b/appl/coupling-ff-pm/iterative/main_pm.cc
@@ -21,35 +21,37 @@
  *
  * \brief A test problem for the coupled Stokes/Darcy problem (1p)
  */
- #include <config.h>
+#include <config.h>
 
- #include <ctime>
- #include <iostream>
+#include <ctime>
+#include <iostream>
 
- #include <dune/common/parallel/mpihelper.hh>
- #include <dune/common/timer.hh>
- #include <dune/grid/io/file/dgfparser/dgfexception.hh>
- #include <dune/grid/io/file/vtk.hh>
- #include <dune/istl/io.hh>
+#include <dune/common/parallel/mpihelper.hh>
+#include <dune/common/timer.hh>
+#include <dune/grid/io/file/dgfparser/dgfexception.hh>
+#include <dune/grid/io/file/vtk.hh>
+#include <dune/istl/io.hh>
 
- #include <dumux/common/properties.hh>
- #include <dumux/common/parameters.hh>
- #include <dumux/common/valgrind.hh>
- #include <dumux/common/dumuxmessage.hh>
- #include <dumux/common/defaultusagemessage.hh>
+#include <dumux/common/properties.hh>
+#include <dumux/common/parameters.hh>
+#include <dumux/common/valgrind.hh>
+#include <dumux/common/dumuxmessage.hh>
+#include <dumux/common/defaultusagemessage.hh>
 
- #include <dumux/linear/amgbackend.hh>
- #include <dumux/nonlinear/newtonsolver.hh>
+#include <dumux/linear/amgbackend.hh>
+#include <dumux/nonlinear/newtonsolver.hh>
 
- #include <dumux/assembly/fvassembler.hh>
- #include <dumux/assembly/diffmethod.hh>
+#include <dumux/assembly/fvassembler.hh>
+#include <dumux/assembly/diffmethod.hh>
 
- #include <dumux/discretization/method.hh>
+#include <dumux/discretization/method.hh>
 
- #include <dumux/io/vtkoutputmodule.hh>
- #include <dumux/io/grid/gridmanager.hh>
+#include <dumux/io/vtkoutputmodule.hh>
+#include <dumux/io/grid/gridmanager.hh>
 
- #include "../monolithic/pmproblem.hh"
+#include "../monolithic/pmproblem.hh"
+
+#include "../precice/preciceadapter.hh"
 
  /*!
   * \brief Returns the pressure at the interface using Darcy's law for reconstruction
@@ -84,6 +86,37 @@
            + ccPressure;
  }
 
+ template<class Problem, class GridVariables, class SolutionVector>
+ void setBoundaryHeatFluxes(const Problem& problem,
+                            const GridVariables& gridVars,
+                            const SolutionVector& sol)
+ {
+   const auto& fvGridGeometry = problem.fvGridGeometry();
+   auto fvGeometry = localView(fvGridGeometry);
+   auto elemVolVars = localView(gridVars.curGridVolVars());
+   auto elemFaceVars = localView(gridVars.curGridFaceVars());
+
+   auto& couplingInterface = precice_adapter::PreciceAdapter::getInstance();
+
+   for (const auto& element : elements(fvGridGeometry.gridView()))
+   {
+     fvGeometry.bindElement(element);
+     elemVolVars.bindElement(element, fvGeometry, sol);
+     elemFaceVars.bindElement(element, fvGeometry, sol);
+
+     for (const auto& scvf : scvfs(fvGeometry))
+     {
+
+       if ( couplingInterface.isCoupledEntity( scvf.index() ) )
+       {
+         //TODO: What to do here?
+//         couplingInterface.pressureAtInterface( problem, element, scvf, elemVolVars, ??? );
+       }
+     }
+   }
+
+ }
+
 int main(int argc, char** argv) try
 {
     using namespace Dumux;
@@ -119,6 +152,62 @@ int main(int argc, char** argv) try
     GetPropType<DarcyTypeTag, Properties::SolutionVector> sol;
     sol.resize(darcyFvGridGeometry->numDofs());
 
+    // Initialize preCICE.Tell preCICE about:
+    // - Name of solver
+    // - What rank of how many ranks this instance is
+    // Configure preCICE. For now the config file is hardcoded.
+    //couplingInterface.createInstance( "darcy", mpiHelper.rank(), mpiHelper.size() );
+    std::string preciceConfigFilename = "precice-config.xml";
+    if (argc == 3)
+      preciceConfigFilename = argv[2];
+
+    auto& couplingInterface =
+        precice_adapter::PreciceAdapter::getInstance();
+    couplingInterface.announceSolver( "Darcy", preciceConfigFilename,
+                                      mpiHelper.rank(), mpiHelper.size() );
+
+    const auto velocityId = couplingInterface.announceQuantity( "Velocity" );
+    const auto pressureId = couplingInterface.announceQuantity( "Pressure" );
+
+    const int dim = couplingInterface.getDimensions();
+    std::cout << dim << "  " << int(DarcyFVGridGeometry::GridView::dimension) << std::endl;
+    if (dim != int(DarcyFVGridGeometry::GridView::dimension))
+        DUNE_THROW(Dune::InvalidStateException, "Dimensions do not match");
+
+    // GET mesh corodinates
+    const double xMin = getParamFromGroup<std::vector<double>>("Darcy", "Grid.Positions0")[0];
+    const double xMax = getParamFromGroup<std::vector<double>>("Darcy", "Grid.Positions0").back();
+    std::vector<double> coords; //( dim * vertexSize );
+    std::vector<int> coupledScvfIndices;
+
+    for (const auto& element : elements(darcyGridView))
+    {
+        auto fvGeometry = localView(*darcyFvGridGeometry);
+        fvGeometry.bindElement(element);
+
+        for (const auto& scvf : scvfs(fvGeometry))
+        {
+            static constexpr auto eps = 1e-7;
+            const auto& pos = scvf.center();
+            if (pos[1] < darcyFvGridGeometry->bBoxMin()[1] + eps)
+            {
+                if (pos[0] > xMin - eps && pos[0] < xMax + eps)
+                {
+                  coupledScvfIndices.push_back(scvf.index());
+                    for (const auto p : pos)
+                        coords.push_back(p);
+                }
+            }
+        }
+    }
+
+    const auto numberOfPoints = coords.size() / dim;
+    const double preciceDt = couplingInterface.setMeshAndInitialize( "darcyMesh",
+                                                                     numberOfPoints,
+                                                                     coords,
+                                                                     coupledScvfIndices );
+
+
     darcyProblem->applyInitialSolution(sol);
 
     // the grid variables
@@ -135,6 +224,16 @@ int main(int argc, char** argv) try
     GetPropType<DarcyTypeTag, Properties::IOFields>::initOutputModule(darcyVtkWriter);
     darcyVtkWriter.write(0.0);
 
+
+    if ( couplingInterface.hasToWriteInitialData() )
+    {
+      //TODO
+      //couplingInterface.writeQuantityVector(velocityId);
+      couplingInterface.writeQuantityToOtherSolver( velocityId );
+      couplingInterface.announceInitialDataWritten();
+    }
+    couplingInterface.initializeData();
+
     // the assembler for a stationary problem
     using Assembler = FVAssembler<DarcyTypeTag, DiffMethod::numeric>;
     auto assembler = std::make_shared<Assembler>(darcyProblem, darcyFvGridGeometry, darcyGridVariables);
@@ -147,12 +246,52 @@ int main(int argc, char** argv) try
     using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>;
     NewtonSolver nonLinearSolver(assembler, linearSolver);
 
-    // solve the non-linear system
-    nonLinearSolver.solve(sol);
+    auto dt = preciceDt;
+    auto sol_checkpoint = sol;
 
+    while ( couplingInterface.isCouplingOngoing() )
+    {
+        if ( couplingInterface.hasToWriteIterationCheckpoint() )
+        {
+            //DO CHECKPOINTING
+            sol_checkpoint = sol;
+            couplingInterface.announceIterationCheckpointWritten();
+        }
+
+        // TODO
+        couplingInterface.readQuantityFromOtherSolver( pressureId );
+
+        // solve the non-linear system
+        nonLinearSolver.solve(sol);
+        // TODO
+        // FILL DATA vector
+        //      couplingInterface.writeQuantityVector( pressureId );
+        couplingInterface.writeQuantityToOtherSolver( velocityId );
+
+        const double preciceDt = couplingInterface.advance( dt );
+        dt = std::min( preciceDt, dt );
+
+        if ( couplingInterface.hasToReadIterationCheckpoint() )
+        {
+            //Read checkpoint
+            sol = sol_checkpoint;
+            //darcyGridVariables->update(sol);
+            //darcyGridVariables->advanceTimeStep();
+            darcyGridVariables->init(sol);
+            couplingInterface.announceIterationCheckpointRead();
+        }
+        else // coupling successful
+        {
+          // write vtk output
+          darcyVtkWriter.write(1.0);
+        }
+
+    }
     // write vtk output
     darcyVtkWriter.write(1.0);
 
+    couplingInterface.finalize();
+
     ////////////////////////////////////////////////////////////
     // finalize, print dumux message to say goodbye
     ////////////////////////////////////////////////////////////
diff --git a/appl/coupling-ff-pm/monolithic/ffproblem.hh b/appl/coupling-ff-pm/monolithic/ffproblem.hh
index 35a2a43..7907372 100644
--- a/appl/coupling-ff-pm/monolithic/ffproblem.hh
+++ b/appl/coupling-ff-pm/monolithic/ffproblem.hh
@@ -36,6 +36,8 @@
 #include <dumux/discretization/staggered/freeflow/properties.hh>
 #include <dumux/freeflow/navierstokes/model.hh>
 
+#include "../precice/preciceadapter.hh"
+
 namespace Dumux
 {
 template <class TypeTag>
@@ -120,10 +122,16 @@ public:
     : ParentType(fvGridGeometry, "Stokes"), eps_(1e-6), couplingManager_(couplingManager)
 #else
     StokesSubProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
-    : ParentType(fvGridGeometry, "Stokes"), eps_(1e-6)
+      : ParentType(fvGridGeometry, "Stokes"),
+        eps_(1e-6),
+        couplingInterface_(precice_adapter::PreciceAdapter::getInstance() ),
+        pressureId_(couplingInterface_.getIdFromName( "Pressure" ) ),
+        velocityId_(couplingInterface_.getIdFromName( "Velocity" ) )
 #endif
     {
         deltaP_ = getParamFromGroup<Scalar>(this->paramGroup(), "Problem.PressureDifference");
+//        pressureId_ =  couplingInterface_.getIdFromName( "Pressure" );
+//        velocityId_ = couplingInterface_.getIdFromName( "Velocity" );
     }
 
    /*!
@@ -188,12 +196,14 @@ public:
         }
 #else
     // // TODO do preCICE stuff in analogy to heat transfer
-    // if(/*preCice*/)
-    // {
-    //     values.setCouplingNeumann(Indices::conti0EqIdx);
-    //     values.setCouplingNeumann(Indices::momentumYBalanceIdx);
-    //     values.setBJS(Indices::momentumXBalanceIdx);
-    // }
+        const auto faceId = scvf.index();
+        if ( couplingInterface_.isCoupledEntity(faceId) )
+        {
+          //TODO What do I want to do here?
+          //     values.setCouplingNeumann(Indices::conti0EqIdx);
+          //     values.setCouplingNeumann(Indices::momentumYBalanceIdx);
+          //     values.setBJS(Indices::momentumXBalanceIdx);
+        }
 #endif
 
         return values;
@@ -236,6 +246,13 @@ public:
             values[Indices::momentumYBalanceIdx] = couplingManager().couplingData().momentumCouplingCondition(element, fvGeometry, elemVolVars, elemFaceVars, scvf);
         }
 #else
+        const auto faceId = scvf.index();
+        if( couplingInterface_.isCoupledEntity( faceId ) )
+        {
+          const Scalar density = 1000; // TODO how to handle compressible fluids?
+          values[Indices::conti0EqIdx] = elemFaceVars[scvf].velocitySelf() * scvf.directionSign() * density;
+          values[Indices::momentumYBalanceIdx] = couplingInterface_.getQuantityOnFace( pressureId_, faceId );
+        }
         // if(/*preCICE*/)
         // {
         //     const Scalar density = 1000; // TODO how to handle compressible fluids?
@@ -358,6 +375,10 @@ private:
 
 #if ENABLEMONOLITHIC
     std::shared_ptr<CouplingManager> couplingManager_;
+#else
+   precice_adapter::PreciceAdapter& couplingInterface_;
+   const size_t pressureId_;
+   const size_t velocityId_;
 #endif
 
     mutable std::vector<Scalar> analyticalVelocityX_;
diff --git a/appl/coupling-ff-pm/monolithic/pmproblem.hh b/appl/coupling-ff-pm/monolithic/pmproblem.hh
index 49565ca..479bca7 100644
--- a/appl/coupling-ff-pm/monolithic/pmproblem.hh
+++ b/appl/coupling-ff-pm/monolithic/pmproblem.hh
@@ -43,6 +43,8 @@
 #include <dumux/material/components/simpleh2o.hh>
 #include <dumux/material/fluidsystems/1pliquid.hh>
 
+#include "../precice/preciceadapter.hh"
+
 namespace Dumux
 {
 template <class TypeTag>
@@ -124,7 +126,10 @@ public:
     : ParentType(fvGridGeometry, "Darcy"), eps_(1e-7), couplingManager_(couplingManager)
 #else
 DarcySubProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
-    : ParentType(fvGridGeometry, "Darcy"), eps_(1e-7)
+    : ParentType(fvGridGeometry, "Darcy"), eps_(1e-7),
+      couplingInterface_(precice_adapter::PreciceAdapter::getInstance() ),
+      pressureId_(couplingInterface_.getIdFromName( "Pressure" ) ),
+      velocityId_(couplingInterface_.getIdFromName( "Velocity" ) )
 #endif
     {}
 
@@ -209,6 +214,11 @@ DarcySubProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
         if (couplingManager().isCoupledEntity(CouplingManager::darcyIdx, scvf))
             values[Indices::conti0EqIdx] = couplingManager().couplingData().massCouplingCondition(element, fvGeometry, elemVolVars, scvf);
 #else
+        const auto faceId = scvf.index();
+        if ( couplingInterface_.isCoupledEntity(faceId) )
+        {
+          values[Indices::conti0EqIdx] = - couplingInterface_.getQuantityOnFace( velocityId_, faceId );
+        }
         // if (/*preCICE*/)
         // {
         //     values[Indices::conti0EqIdx] = /*mass flux from stokes*/;
@@ -279,6 +289,10 @@ private:
 
 #if ENABLEMONOLITHIC
     std::shared_ptr<CouplingManager> couplingManager_;
+#else
+   precice_adapter::PreciceAdapter& couplingInterface_;
+   const size_t pressureId_;
+   const size_t velocityId_;
 #endif
 };
 } //end namespace
diff --git a/doc/mkdocs/dumux_precice/docs/dumux_precice_coupling.md b/doc/mkdocs/dumux_precice/docs/dumux_precice_coupling.md
index 6029ee3..43b3a20 100644
--- a/doc/mkdocs/dumux_precice/docs/dumux_precice_coupling.md
+++ b/doc/mkdocs/dumux_precice/docs/dumux_precice_coupling.md
@@ -2,6 +2,29 @@
 
 ## Milestones
 
+### Free flow and poious media flow coupling
+
+We plan to do the following
+
+| Solver | writes | reads |
+| ------ | ------ | ----- |
+| FreeFlow | Pressure | Velocity |
+| Darcy | Velocity | Pressure |
+
+The data is then incorporated into the BJS boundary conditions. Hopefully in a smart way.
+
+#### Questions
+
+In FreeFlow `ffproblem.hh`
+
+- Should alphaBJ and permeability be transfered? I thought they would be constant?
+
+In Darcy
+
+- Do we receive mass flux or velocity?
+- How to reconstruct certain things some stuff?!
+
+
 ### Conjugate heat transfer problem 
 
 See [test case description](dumux_test_case.md#conjugate-heat-transfer) 
-- 
GitLab