diff --git a/common/configuration.h b/common/configuration.h
index 8818d6b341c14aebcc1dee9fb91e28cac8b91a17..fb346bbbb019bee519b447c80d5c18677987d12d 100644
--- a/common/configuration.h
+++ b/common/configuration.h
@@ -6,6 +6,7 @@
 #include "Domain.h"
 //Standard Library
 #include <array>
+#include <map>
 //GmshFWI Library
 #include "model/element.h"
 #include "model/parametrization.h"
@@ -21,6 +22,7 @@ protected:
     std::array<gmshfem::domain::Domain,2> _wave_omega;
     std::array<gmshfem::domain::Domain,2> _model_known;
     std::array<gmshfem::domain::Domain,2> _model_unknown;
+    std::map<std::string, gmshfem::domain::Domain> _named_domains;
     gmshfem::domain::Domain _data_omega;
 
     unsigned int _np;
@@ -74,6 +76,7 @@ public:
     gmshfem::domain::Domain model_evaldomain() const {return _model_unknown[Support::BLK] | _model_unknown[Support::BND];};
     gmshfem::domain::Domain wave_evaldomain() const {return _wave_omega[Support::BLK]  | _wave_omega[Support::BND] | _points;};
     gmshfem::domain::Domain data_evaldomain() const {return _data_omega;};
+    const std::map<std::string, gmshfem::domain::Domain>& named_domains() const {return _named_domains;}
 
     gmshfem::domain::Domain emitter(unsigned int shot, unsigned int em) const;
     gmshfem::domain::Domain receiver(unsigned int shot, unsigned int rec) const;
diff --git a/specific/configuration/surface_acquisition.cpp b/specific/configuration/surface_acquisition.cpp
index 0a81f151044eba1020d48131d49c5578c27c307e..37ed89dcaf96ef81a2eb274393bdaccbc744a1a4 100644
--- a/specific/configuration/surface_acquisition.cpp
+++ b/specific/configuration/surface_acquisition.cpp
@@ -113,6 +113,8 @@ namespace surface_acquisition
         _supersurface[Support::BLK] = Domain(2, 22);
         _supersurface[Support::BND] = Domain(1, 12);
 
+        _named_domains["top_bnd"] = Domain("top_bnd");
+
         _wave_omega[Support::BLK] = _subsurface[Support::BLK] | _supersurface[Support::BLK];
         _wave_omega[Support::BND] = _subsurface[Support::BND] | _supersurface[Support::BND];
 
@@ -341,6 +343,7 @@ namespace surface_acquisition
                 lymin_reverse[n] = -lymin[n];
             }
 
+            // Nomenclature: line from one y to another, left or right. All lines go up
             int lHyminl = factory::addLine(pHl,pyminl);
             int lymin0l = factory::addLine(pyminl,p0l);
             int l0ymaxl = factory::addLine(p0l,pymaxl);
@@ -430,6 +433,10 @@ namespace surface_acquisition
             gmodel::addPhysicalGroup(1, lsuper, 12);
             gmodel::setPhysicalName(1, 12, "supersurface_bnd");
 
+            // Add another physical groupe for the top boundary, to represent e.g. reflection at the air-water interface
+            gmodel::addPhysicalGroup(1, lymax, 13);
+            gmodel::setPhysicalName(1, 13, "top_bnd");
+
             gmodel::addPhysicalGroup(2, {s_sub}, 21);
             gmodel::setPhysicalName(2, 21, "subsurface_vol");
             gmodel::addPhysicalGroup(2, {s_supermin,s_supermax}, 22);
@@ -507,6 +514,10 @@ namespace surface_acquisition
             gmodel::addPhysicalGroup(1, lsuper, 12);
             gmodel::setPhysicalName(1, 12, "supersurface_bnd");
 
+            // Add another physical groupe for the top boundary, to represent e.g. reflection at the air-water interface
+            gmodel::addPhysicalGroup(1, lymax, 13);
+            gmodel::setPhysicalName(1, 13, "top_bnd");
+
             gmodel::addPhysicalGroup(2, {s_sub}, 21);
             gmodel::setPhysicalName(2, 21, "subsurface_vol");
             gmodel::addPhysicalGroup(2, {s_supermax}, 22);
diff --git a/specific/wave/equation/simplewave.cpp b/specific/wave/equation/simplewave.cpp
index 499781c96d0d767370a5f4d323e75ba678e11e92..b2fe3c972cdd03307245449e0c39aa6cfe79019c 100644
--- a/specific/wave/equation/simplewave.cpp
+++ b/specific/wave/equation/simplewave.cpp
@@ -72,6 +72,15 @@ namespace simplewave
         {
                 throw Exception("Impossible to compute boundary terms with real impedance: sensitivities are wrong.");
         }
+
+        if (gmshFem.userDefinedParameter(_topBC, "top_bc")) {
+            if (_topBC != "Absorbing" && _topBC != "Dirichlet" && _topBC != "Neumann") {
+                throw Exception("Invalid value of parameter top_bc: " + _topBC);
+            }
+        }
+        else {
+            msg::warning << "SimpleWave without specified top_bc defaults to Absorbing." << msg::endl;
+        }
     }
 
     bool Equation::modelIsObsolete()
@@ -104,16 +113,35 @@ namespace simplewave
     }
     void Equation::setLHS(const ModelStateEvaluator& ms)
     {
+        auto top = _config->named_domains().find("top_bnd");
+        if (_topBC == "Dirichlet" || _topBC == "Neumann")
+        {
+            if (top == _config->named_domains().end())
+                throw Exception("Asked for specific BCs on top but this entity isn't defined.");
+        }
+
+        if (_topBC == "Dirichlet")
+        {
+            _v.addConstraint(top->second, 0.0);
+        }
+
         _formulation.integral(-1.*grad(dof(_v)), grad(tf(_v)), _config->wave_omega(Support::BLK),integrationType(2*_w_degree));
         _formulation.integral(_pulsation * _pulsation * m0 * dof(_v), tf(_v), _config->model_known(Support::BLK), integrationType(_integrationDegreeBlk));
+        
+        auto absorbingPartKnown = _config->model_known(Support::BND);
+        auto absorbingPartUnknown = _config->model_unknown(Support::BND);
+        if (_topBC == "Neumann") {
+            absorbingPartKnown &= ~(top->second);
+            absorbingPartUnknown &= ~(top->second);
+        }
 
         if(_realImpedance)
         {
-            _formulation.integral(-1. * im * _pulsation * sqrt(real(m0)) * dof(_v), tf(_v), _config->model_known(Support::BND), integrationType(_integrationDegreeBnd)); //-1 from sign conventions
+            _formulation.integral(-1. * im * _pulsation * sqrt(real(m0)) * dof(_v), tf(_v), absorbingPartKnown, integrationType(_integrationDegreeBnd)); //-1 from sign conventions
         }
         else
         {
-            _formulation.integral(-1. * im * _pulsation * sqrt(m0) * dof(_v), tf(_v), _config->model_known(Support::BND), integrationType(_integrationDegreeBnd)); //-1 from sign conventions
+            _formulation.integral(-1. * im * _pulsation * sqrt(m0) * dof(_v), tf(_v), absorbingPartKnown, integrationType(_integrationDegreeBnd)); //-1 from sign conventions
         }
         if(!_config->model_unknown(Support::BLK).isEmpty())
         {
@@ -123,11 +151,11 @@ namespace simplewave
         {
             if(_realImpedance)
             {
-                _formulation.integral(-1. * im * _pulsation * sqrt(real(m)) *  dof(_v), tf(_v), _config->model_unknown(Support::BND), integrationType(_integrationDegreeBnd)); //-1 from sign conventions
+                _formulation.integral(-1. * im * _pulsation * sqrt(real(m)) *  dof(_v), tf(_v), absorbingPartUnknown, integrationType(_integrationDegreeBnd)); //-1 from sign conventions
             }
             else
             {
-                _formulation.integral(-1. * im * _pulsation * sqrt(m) *  dof(_v), tf(_v), _config->model_unknown(Support::BND), integrationType(_integrationDegreeBnd)); //-1 from sign conventions
+                _formulation.integral(-1. * im * _pulsation * sqrt(m) *  dof(_v), tf(_v), absorbingPartUnknown, integrationType(_integrationDegreeBnd)); //-1 from sign conventions
             }
         }
     }
diff --git a/specific/wave/equation/simplewave.h b/specific/wave/equation/simplewave.h
index 0acee2dd67c44b19b7f41fa51d4fa0e51c731e78..2cbe35d648b5d907c4ebe90f62096b9ffa384909 100644
--- a/specific/wave/equation/simplewave.h
+++ b/specific/wave/equation/simplewave.h
@@ -21,6 +21,7 @@ namespace simplewave
         bool _realImpedance;
         double _const_preconditioner;
         using EquationInterface<Physic::acoustic>::_boundary;
+        std::string _topBC;
     public:
         Equation(unsigned int f_idx,double pulsation,const ConfigurationInterface* const config, const wave::Discretization<Physic::acoustic>& w_discret,const gmshfem::common::GmshFem& gmshFem, std::string suffix = "");