diff --git a/dune/grid/uggrid.hh b/dune/grid/uggrid.hh
index 7a63e40d1e847301b3dc5e8759806d13aafba71f..6f1f6cf30c2280c73f2090acc828300ac54205a2 100644
--- a/dune/grid/uggrid.hh
+++ b/dune/grid/uggrid.hh
@@ -43,13 +43,6 @@
    But we also need the headers twice!  Once with UG_DIM_2 set and once with UG_DIM_3!
    So here we go:*/
 
-/* The following define tells the UG headers that we want access to a few
-   special fields, for example the extra index fields in the element data structures.
-   This define remains only for backwards compatibility with older version of UG.
-   All dune-uggrid versions since 2016-08-05 do not need this #define or the #undef
-   further below. */
-#define FOR_DUNE
-
 // Set UG's space-dimension flag to 2d
 #define UG_DIM_2
 // And include all necessary UG headers
@@ -97,7 +90,6 @@
 #include "uggrid/ug_undefs.hh"
 
 #undef UG_DIM_3
-#undef FOR_DUNE
 
 // The components of the UGGrid interface
 #include "uggrid/uggridgeometry.hh"
@@ -664,6 +656,15 @@ namespace Dune {
     /** \brief UG multigrid, which contains the actual grid hierarchy structure */
     typename UG_NS<dim>::MultiGrid* multigrid_;
 
+    /** \brief The UG3 BoundaryValueProblem, a description of the domain boundary
+     *
+     * \todo The multigrid_ object also has pointer to this.  I don't like this
+     * redundancy, but I also don't quite know yet what to do about it.
+     *
+     * \note BVP is a pointer type!
+     */
+    typename UG_NS<dim>::BVP bvp_;
+
     /** \brief The communication object. */
     UGCommunication ccobj_;
 
diff --git a/dune/grid/uggrid/uggrid.cc b/dune/grid/uggrid/uggrid.cc
index 5528776fa79f5464801fd2a2527222c81ccd8fc3..729a507b9167c39ea81cc7f2d0c62b3537ff9649 100644
--- a/dune/grid/uggrid/uggrid.cc
+++ b/dune/grid/uggrid/uggrid.cc
@@ -85,10 +85,6 @@ UGGrid < dim >::UGGrid(UGCommunication comm)
     free(arg);
   }
 
-  // Create a dummy problem
-  typename UG_NS<dim>::CoeffProcPtr coeffs[1] = {nullptr};
-  typename UG_NS<dim>::UserProcPtr upp[1] = {nullptr};
-
   // Create unique problem name
   std::stringstream numberAsAscii;
   numberAsAscii << numOfUGGrids;
@@ -96,8 +92,7 @@ UGGrid < dim >::UGGrid(UGCommunication comm)
 
   std::string problemName = name_ + "_Problem";
 
-  if (UG_NS<dim>::CreateBoundaryValueProblem(problemName.c_str(), 1,coeffs,1,upp) == nullptr)
-    DUNE_THROW(GridError, "UG" << dim << "d::CreateBoundaryValueProblem() returned an error code!");
+  bvp_ = new typename UG_NS<dim>::STD_BVP;
 
   numOfUGGrids++;
 
@@ -110,6 +105,7 @@ template < int dim >
 UGGrid < dim >::~UGGrid() noexcept(false)
 {
   // Delete the UG multigrid if there is one (== createEnd() has been called)
+  // DisposeMultiGrid cleans up the BVP as well.
   if (multigrid_) {
     // Set UG's currBVP variable to the BVP corresponding to this
     // grid.  This is necessary if we have more than one UGGrid in use.
@@ -119,17 +115,6 @@ UGGrid < dim >::~UGGrid() noexcept(false)
       DUNE_THROW(GridError, "UG" << dim << "d::DisposeMultiGrid returned error code!");
   }
 
-  // DisposeMultiGrid cleans up the BVP as well.  But if there was no
-  // multigrid we have to take care of the BVP ourselves.
-  std::string problemName = name_ + "_Problem";
-  void** BVP = UG_NS<dim>::BVP_GetByName(problemName.c_str());
-
-  if (BVP)
-    if (UG_NS<dim>::BVP_Dispose(BVP))
-      DUNE_THROW(GridError, "Couldn't dispose of UG boundary value problem!");
-
-
-
   numOfUGGrids--;
 
   // Shut down UG if this was the last existing UGGrid object.
@@ -650,7 +635,6 @@ template <int dim>
 void UGGrid<dim>::loadState(const std::string& filename)
 {
   const char* type = "asc";
-  std::string problemName = name_ + "_Problem";
   std::string formatName = "DuneFormat2d";
 
   if (dim==2) {
@@ -659,7 +643,7 @@ void UGGrid<dim>::loadState(const std::string& filename)
       name_.c_str(),
       filename.c_str(),
       type,
-      problemName.c_str(),
+      nullptr,  // dummy BVP point -- this will crash!
       formatName.c_str(),
       0,    // dummy heap size
       true, //force,
@@ -675,7 +659,7 @@ void UGGrid<dim>::loadState(const std::string& filename)
       name_.c_str(),
       filename.c_str(),
       type,
-      problemName.c_str(),
+      nullptr,  // dummy BVP point -- this will crash!
       formatName.c_str(),
       0,    // dummy heap size
       true, //force,
diff --git a/dune/grid/uggrid/uggridfactory.cc b/dune/grid/uggrid/uggridfactory.cc
index 8e5559475dd51be9c7bbcc02cfc73c98ffe40f32..f8f8a53d6913c9737353f76d3cf3883d784aeb1e 100644
--- a/dune/grid/uggrid/uggridfactory.cc
+++ b/dune/grid/uggrid/uggridfactory.cc
@@ -407,18 +407,9 @@ createGrid()
   /////////////////////////////////////////////////
 
   std::string MultiGridName = grid_->name_;
-  std::string BVPName = MultiGridName + "_Problem";
   std::string FormatName = "DuneFormat" + std::to_string(dimworld) + "d";
 
-  typename UG_NS<dimworld>::BVP* theBVP = UG_NS<dimworld>::BVP_GetByName(BVPName.c_str());
-  assert(theBVP);
-
-  typename UG_NS<dimworld>::BVP_DESC theBVPDesc;
-  if (BVP_SetBVPDesc(theBVP,&theBVPDesc) != 0)
-    DUNE_THROW(GridError, "Calling BVP_SetBVPDesc failed!");
-
-  if (STD_BVP_Configure(BVPName,std::move(ugDomain)))
-    DUNE_THROW(GridError, "Calling STD_BVP_Configure failed!");
+  grid_->bvp_->Domain = std::move(ugDomain);
 
   // Make sure there is no old multigrid object with the same name.
   // TODO: Can this happen at all?
@@ -431,7 +422,7 @@ createGrid()
 #if ModelP and DUNE_UGGRID_HAVE_PPIFCONTEXT
   ppifContext = std::make_shared<PPIF::PPIFContext>(grid_->comm());
 #endif
-  grid_->multigrid_ = UG_NS<dimworld>::CreateMultiGrid(MultiGridName.c_str(),BVPName.c_str(),FormatName.c_str(),true,true, ppifContext);
+  grid_->multigrid_ = UG_NS<dimworld>::CreateMultiGrid(MultiGridName.c_str(),grid_->bvp_,FormatName.c_str(),true,true, ppifContext);
   if (grid_->multigrid_==nullptr)
     DUNE_THROW(GridError, "Could not create multigrid");
 
diff --git a/dune/grid/uggrid/ugwrapper.hh b/dune/grid/uggrid/ugwrapper.hh
index 3e5de108d13b8d04aa3477c7991e8fca1b967684..b4f28c579e28a309d2e85a43a99c90a3c9f13e08 100644
--- a/dune/grid/uggrid/ugwrapper.hh
+++ b/dune/grid/uggrid/ugwrapper.hh
@@ -54,10 +54,6 @@ namespace Dune {
 
     typedef UG_NAMESPACE ::RefinementRule RefinementRule;
 
-    typedef UG_NAMESPACE ::CoeffProcPtr CoeffProcPtr;
-
-    typedef UG_NAMESPACE ::UserProcPtr UserProcPtr;
-
     typedef UG_NAMESPACE ::BndSegFuncPtr BndSegFuncPtr;
 
     /** \brief This is actually a type of the UG algebra, not the grid.
@@ -83,7 +79,7 @@ namespace Dune {
 
     typedef UG_NAMESPACE ::BVP BVP;
 
-    typedef UG_NAMESPACE ::BVP_DESC BVP_DESC;
+    typedef UG_NAMESPACE ::STD_BVP STD_BVP;
 
     /** \brief Point on a UG boundary patch */
     typedef UG_NAMESPACE ::BNDP BNDP;
@@ -1063,31 +1059,11 @@ namespace Dune {
       return UG_NAMESPACE ::DisposeMultiGrid(mg);
     }
 
-    //! \todo Please doc me!
-    static void* CreateBoundaryValueProblem(const char* BVPname,
-                                            int numOfCoeffFunc,
-                                            UG_NAMESPACE ::CoeffProcPtr coeffs[],
-                                            int numOfUserFct,
-                                            UG_NAMESPACE ::UserProcPtr userfct[]) {
-      return UG_NAMESPACE ::CreateBoundaryValueProblem(BVPname, 0, numOfCoeffFunc, coeffs,
-                                                       numOfUserFct, userfct);
-    }
-
     //! Set the current boundary value problem
-    static void Set_Current_BVP(void** thisBVP) {
+    static void Set_Current_BVP(UG_NAMESPACE ::STD_BVP** thisBVP) {
       UG_NAMESPACE ::Set_Current_BVP(thisBVP);
     }
 
-    //! Get UG boundary value problem from its name
-    static void** BVP_GetByName(const char* name) {
-      return UG_NAMESPACE ::BVP_GetByName(name);
-    }
-
-    //! Dispose of a boundary value problem
-    static int BVP_Dispose(void** BVP) {
-      return UG_NAMESPACE ::BVP_Dispose(BVP);
-    }
-
     /** \brief Create new point on the grid boundary by giving local coordinates.
 
        Global coordinates are computed automatically using the domain boundary information.
@@ -1133,12 +1109,12 @@ namespace Dune {
 #endif
     }
 
-    static MultiGrid *CreateMultiGrid(const char *MultigridName, const char *BndValProblem,
+    static MultiGrid *CreateMultiGrid(const char *MultigridName, BVP theBVP,
                                       const char *format,
                                       int optimizedIE, int insertMesh,
                                       std::shared_ptr<PPIF::PPIFContext> ppifContext = nullptr) {
       return UG_NAMESPACE ::CreateMultiGrid(const_cast<char*>(MultigridName),
-                                            const_cast<char*>(BndValProblem), format,
+                                            theBVP, format,
                                             optimizedIE, insertMesh, ppifContext);
     }