Commit cef239ed authored by Lukas Riedel's avatar Lukas Riedel 📝 Committed by Santiago Ospina De Los Ríos

Define new data structures for storing boundary conditions

* Define classes of polymorphic boundary conditions and factory
* Only use enum in Operator namespace to discern types
* FlowBoundary now returns an entire boundary condition
* Adapt local operators (Richards only)
* Remove header 'util.hh'. Move functions to 'utility.hh', BaseTraits
  to 'typedefs.hh' and GFS helpers to 'gfs_helper.hh'
* Add setting for `horizontal_projection` of Neumann BC (only used in Richards model) #136 (comment 20384).
* Add setting for `concentration_type` of Dirichlet BC (only used in Transport model) #151.
parent 59cf9b32
......@@ -36,12 +36,12 @@
* Split grid adaptivity process into marking and actual adaptation !91
* Rework VTK adapters and VTK output writer !64
* `RichardsSimulation` now implements the abstract simulation base class !89
* Swich to the stable release branch `releases/2.6` of `dune-testtools` !97
* Switch to the stable release branch `releases/2.6` of `dune-testtools` !97
* Merge Python packages into single new package `dorie` !100
* Move `dorie` Command Line Interface script into Python package !102
* Parameterization data input via YAML and H5 files !82
* Simplify H5 reader to only read datasets !109
* Extend run config file to contain data on multipe models !103
* Extend run config file to contain data on multiple models !103
* DORiE now writes vertex data by default. !128
* Switch license from MIT to GPLv3 !135
* Specifying scaling field `extensions` and `offset` is now optional !133
......@@ -53,6 +53,7 @@
* Build independent library and executable for each compile-time setting !144
* `SimulationBase` unit test now uses Google Test !159
* Deploy online documentation for each branch to private server !163
* Use YAML (instead of muPhi `.bcdat`) files for specifying BCs !121
### Fixed
* Allow meta-ini files for unit tests !101
......@@ -60,6 +61,8 @@
* Shape of input datasets was flipped when loading scaling factors !124
* `dune_add_system_test` requires target with location after bugfix !165
* `make all` would not build the solver application target `dorie` !167
* Allow Neumman BC to be applied on a different direction other than gravity !121
* Transport model option `dirichletMode` was not working properly !121
### Deprecated
......
......@@ -95,6 +95,11 @@ function(dorie_add_unit_test)
muparser::muparser hdf5 yaml-cpp spdlog)
# add_coverage_links(${UNIT_TEST_TARGET})
target_compile_definitions(${UNIT_TEST_TARGET}
PUBLIC
GTEST
)
if (UNIT_TEST_CUSTOM_MAIN)
target_link_libraries(${UNIT_TEST_TARGET} gtest)
else ()
......@@ -232,6 +237,11 @@ function(dorie_add_metaini_test)
# add_coverage_links(${created_targets})
add_dependencies(build_unit_tests ${created_targets})
target_compile_definitions(${created_targets}
PUBLIC
GTEST
)
if (SYSTEM_TEST_CUSTOM_MAIN)
target_link_libraries(${created_targets} gtest)
else ()
......
......@@ -7,8 +7,8 @@ configure_file(${CMAKE_CURRENT_BINARY_DIR}/tutorial-1.ini
COPYONLY)
# Copy files needed for the test to run
configure_file(${CMAKE_BINARY_DIR}/doc/default_files/2d_infiltr.bcdat
2d_infiltr.bcdat
configure_file(${CMAKE_BINARY_DIR}/doc/default_files/infiltration.yml
infiltration.yml
COPYONLY)
configure_file(${CMAKE_BINARY_DIR}/doc/default_files/richards_param.yml
richards_param.yml
......
......@@ -27,7 +27,7 @@ quantity = matricHead
equation = -h
[richards.boundary]
file = 2d_infiltr.bcdat
file = infiltration.yml
[richards.output]
fileName = infiltr_homogeneous_sand_2D
......
......@@ -121,7 +121,7 @@ Boundary Condition
The :doc:`boundary conditions file </manual/bcfile>` has to be specified by the
keyword ``richards.boundary.file`` in the configuration file. For now, we will
use the infiltration file for 2D, ``2d_infiltr.bcdat``, provided by the command
use the infiltration file, ``infiltration.yml``, provided by the command
``dorie create``. By default, this file sets a constant infiltration of
:math:`j_w = -5.55\cdot 10^{-6}\,\text{ms}^{-1}` at the top, a constant matric
head of :math:`h_m = 0\,\text{m}` at the bottom, and a no-flux condition on the
......@@ -194,6 +194,6 @@ shown below.
============= ======================================================================
Configuration :download:`config.ini <config.ini>`
Boundary :download:`2d_infiltr.bcdat </default_files/2d_infiltr.bcdat>`
Boundary :download:`infiltration.yml </default_files/infiltration.yml>`
Parameters :download:`richards_param.yml </default_files/richards_param.yml>`
============= ======================================================================
spatial_resolution_north 0
spatial_resolution_south 0
spatial_resolution_west -1
spatial_resolution_east -1
number_BC_change_times 1
0 neumann -5.55e-6 dirichlet 0
\ No newline at end of file
spatial_resolution_north 2 0.25 0.75
spatial_resolution_south -1
spatial_resolution_west -1
spatial_resolution_east -1
number_BC_change_times 2
0 neumann 0 dirichlet 1 neumann 0
1E3 neumann 0 neumann 0 neumann 0
spatial_resolution_north_we 0
spatial_resolution_north_fb 0
spatial_resolution_south_we 0
spatial_resolution_south_fb 0
spatial_resolution_west_sn -1
spatial_resolution_west_fb -1
spatial_resolution_east_sn -1
spatial_resolution_east_fb -1
spatial_resolution_front_sn -1
spatial_resolution_front_we -1
spatial_resolution_back_sn -1
spatial_resolution_back_we -1
number_BC_change_times 1
0 neumann -5.55e-6 dirichlet 0
\ No newline at end of file
spatial_resolution_north_we 2 0.25 0.75
spatial_resolution_north_fb 2 0.25 0.75
spatial_resolution_south_we -1
spatial_resolution_south_fb -1
spatial_resolution_west_sn -1
spatial_resolution_west_fb -1
spatial_resolution_east_sn -1
spatial_resolution_east_fb -1
spatial_resolution_front_sn -1
spatial_resolution_front_we -1
spatial_resolution_back_sn -1
spatial_resolution_back_we -1
number_BC_change_times 2
0 neumann 0 neumann 0 neumann 0 neumann 0 dirichlet 1 neumann 0 neumann 0 neumann 0 neumann 0
1E3 neumann 0 neumann 0 neumann 0 neumann 0 neumann 0 neumann 0 neumann 0 neumann 0 neumann 0
\ No newline at end of file
......@@ -117,9 +117,10 @@ function(create_default_config INPUT OUTPUT SOURCE_DIR CSS)
endfunction()
# copy BC & parameter files
file(COPY 2d_infiltr.bcdat 3d_infiltr.bcdat
2d_solute.bcdat 3d_solute.bcdat
richards_param.yml transport_param.yml
file(COPY infiltration.yml
solute.yml
richards_param.yml
transport_param.yml
DESTINATION .)
# Random field generator
......
upper:
index: 1
conditions:
heavy_rainfall:
type: Neumann
time: 0
value: -5.55e-6
horizontal_projection: true
lower:
index: 0
conditions:
water_table:
type: Dirichlet
time: 0
value: 0
default:
type: Neumann
value: 0
......@@ -90,25 +90,11 @@ adding an empty line, make text **bold** or ``monospaced``.
<category name="boundary">
<parameter name="file">
<definition> Path to the boundary condition file. </definition>
<suggestion> 2d_infiltr.bcdat </suggestion>
<definition> Path to the YAML boundary condition data file.
<suggestion> infiltration.yml </suggestion>
</definition>
<values> path </values>
</parameter>
<parameter name="fileType">
<definition> Type of spatial segmentation of the boundaries specified in the BC file </definition>
<values> rectangularGrid </values>
<suggestion> rectangularGrid </suggestion>
<comment> Choose type of boundary segmentation: rectangularGrid </comment>
</parameter>
<parameter name="interpolateBCvalues">
<definition> Whether to interpolate between the boundary conditions
at different times linearly (``true``) or not at all (``false``). May require
different boundary condition files. </definition>
<values> true, false </values>
<suggestion> false </suggestion>
</parameter>
</category>
<category name="initial">
......
upper:
index: 1
conditions:
tracer:
type: Dirichlet
time: 0
value: 1
concentration_type: water_phase
default:
type: Outflow
value: 0
......@@ -101,30 +101,10 @@ adding an empty line, make text **bold** or ``monospaced``.
<category name="boundary">
<parameter name="file">
<definition> Path to the boundary condition file. </definition>
<values> path </values>
</parameter>
<parameter name="fileType">
<definition> Type of spatial segmentation of the boundaries specified in the BC file </definition>
<values> rectangularGrid </values>
<suggestion> rectangularGrid </suggestion>
<comment> Choose type of boundary segmentation: rectangularGrid </comment>
</parameter>
<parameter name="interpolateBCvalues">
<definition> Whether to interpolate between the boundary conditions
at different times linearly (``true``) or not at all (``false``). May require
different boundary condition files. </definition>
<values> true, false </values>
<suggestion> false </suggestion>
</parameter>
<parameter name="dirichletMode">
<definition> Type of the input value for the dirichlet condition.
<definition> Path to the YAML boundary condition data file.
<suggestion> solute.yml </suggestion>
</definition>
<values> soluteConcentration, totalSolute </values>
<suggestion> soluteConcentration </suggestion>
<values> path </values>
</parameter>
</category>
......
spatial_resolution_north 2 0.4 0.8
spatial_resolution_south 0
spatial_resolution_west -1
spatial_resolution_east -1
number_BC_change_times 1
0 neumann 0.0 neumann -5.55e-6 neumann 0.0 dirichlet 0
\ No newline at end of file
spatial_resolution_north_we 2 0.4 0.6
spatial_resolution_north_fb 2 0.4 0.6
spatial_resolution_south_we 0
spatial_resolution_south_fb 0
spatial_resolution_west_sn -1
spatial_resolution_west_fb -1
spatial_resolution_east_sn -1
spatial_resolution_east_fb -1
spatial_resolution_front_sn -1
spatial_resolution_front_we -1
spatial_resolution_back_sn -1
spatial_resolution_back_we -1
number_BC_change_times 1
0 neumann 0.0 neumann 0.0 neumann 0.0 neumann 0.0 neumann -5.55e-6 neumann 0.0 neumann 0.0 neumann 0.0 neumann 0.0 dirichlet 0
\ No newline at end of file
......@@ -27,10 +27,8 @@ Templates for the required files can conveniently be generated with the
| :ref:`Parameterization Data File | :file:`.yml` | Specifies the soil and solute | :download:`richards_param.yml </default_files/richards_param.yml>`, |
| <man-parameter_file>` | | parameterization type(s) and parameters. | :download:`transport_param.yml </default_files/transport_param.yml>` |
+----------------------------------------+----------------+------------------------------------------+----------------------------------------------------------------------+
| :doc:`Boundary Condition Data File | :file:`.bcdat` | Specifies the boundary segmentation and | :download:`2d_infiltr.bcdat </default_files/2d_infiltr.bcdat>`, |
| </manual/bcfile>` | | the boundary conditions. | :download:`3d_infiltr.bcdat </default_files/3d_infiltr.bcdat>`, |
| | | | :download:`2d_solute.bcdat </default_files/2d_solute.bcdat>`, |
| | | | :download:`3d_solute.bcdat </default_files/3d_solute.bcdat>` |
| :doc:`Boundary Condition Data File | :file:`.yml` | Specifies the boundary segmentation and | :download:`infiltration.yml </default_files/infiltration.yml>`, |
| </manual/bcfile>` | | the boundary conditions. | :download:`solute.yml </default_files/solute.yml>` |
+----------------------------------------+----------------+------------------------------------------+----------------------------------------------------------------------+
| :ref:`GMSH Mesh File | :file:`.gmsh` | Mesh with possibly complicated geometry | --- |
| <man-grid_gmsh>` (optional) | | to build an unstructured grid from. | |
......
*********************************
Boundary Condition Datafile Guide
*********************************
Boundary Conditions
===================
.. contents::
:depth: 3
Overview
========
The boundary condition datafile consists of two parts. First, the spatial segmentation of the boundaries is specified. Then, the actual boundary conditions are stated for all of the specified segments. They include information on the boundary condition type and the associated value, as well as the time from which on the stated condition is applied (time stamp).
.. note:: The semantics of the datafile changes if ``boundary.interpolateBCvalues = true`` is invoked in the parameter file.
Boundary conditions represent the *super-scale physics*, the forcing of the
(larger-scale) sourrounding system onto the simulated system.
After specifying the :doc:`boundary segmentation <man-grid>`, we are able to
define the actual conditions applied at each segment. Like the
:doc:`parameterization data file <man-parameter-file>`, the boundary condition
data file is a YAML_ file. Boundary segments are associated with their
boundary conditions by means of the segment indices.
.. contents::
:depth: 3
:local:
Boundary Condition File
-----------------------
The file determines the boundary conditions at certain times for each boundary
segment. Its file path must be given via the key ``boundary.file`` in the
:doc:`config file <man-config-file>`.
After stating a certain boundary segment, the conditions are listed.
The index is the boundary segment index specified in the
:doc:`grid mapping <man-grid>`. A boundary condition generally consists of
a type, a time interval, and a value. The latter two may be stated as sequences
of values. This way, the time interval may be limited, or a boundary condition
may be interpolated between the specified times. Certain types of boundary
conditions may require additional keys.
.. code:: yaml
<boundary-name>:
index: <int>
conditions:
<cond-1>:
time: <scalar or sequence>
type: <string>
value: <scalar or sequence>
# ... more conditions
# ... more boundaries
default:
type: <string>
value: <scalar>
Default Condition
^^^^^^^^^^^^^^^^^
The ``default`` boundary condition is the only required condition. It lacks
a time specification and is inserted whenever a boundary condition is missing.
This can happen if a certain time interval remains uncovered by the stated
conditions, or a boundary condition is missing from the file (which is allowed
and will not produce warnings).
Time Intervals
^^^^^^^^^^^^^^
When stating several boundary conditions on a boundary segment, all but the
(temporally) final condition must have a time *interval*, i.e., the value of
``time`` must be a sequence of two values. The final condition is automatically
extended until the end of the simulation.
Boundary conditions of the same boundary segment must not overlap in time.
If you wish one condition to follow exactly after the other, make sure that
the end of the first interval matches the start of the second interval exactly.
.. note:: DORiE automatically adjusts its time steps to match a change in
boundary conditions.
Value Interpolation
^^^^^^^^^^^^^^^^^^^
Boundary condition values can be linearly interpolated between the begin and
end time of the condition. To that end, one may use a sequence of two values
as ``value``. The standard time step scheme is second order in time and space
and hence suitable for linear interpolation of boundary conditions.
Boundary Condition Types
------------------------
DORiE currently supports four types of boundary conditions:
Dirichlet
+++++++++
.. object:: dirichlet <head>
Set a fixed matric head [:math:`m`] at the boundary.
.. object:: dirichlet <solute>
Set a fixed solute concentration at the boundary.
Neumann
+++++++
.. object:: neumann <water_flux>
Set a fixed volumetric water flux [:math:`m/s`] at the boundary. Positive values
imply fluxes out of the domain, negative values imply fluxes into the domain.
A boundary condition has the following template:
.. object:: neumann <solute_flux>
.. code:: yaml
Set a fixed volumetric solute flux [:math:`kg/(s\,m^3)`] at the boundary. Positive values
imply fluxes out of the domain, negative values imply fluxes into the domain.
time: <scalar or sequence>
type: <string>
value: <scalar or sequence>
# <additional keys>
.. option:: Dirichlet
Outflow
+++++++
A Dirichlet boundary conditions determines the exact value of the solution
at the boundary.
.. object:: outflow <solute_outflux>
**Richards Model**
Quantity: Matric head :math:`h_m \, [\text{m}]`.
Set a spatial rate of change of volumetric solute flux
[:math:`kg/(s\,m\,m^3)`] at the boundary. Positive values imply higher rate
of change out of the domain, negative values imply lower rate of change into
the domain. Influx situations are not taken into account. For most of the
cases an outflow of 0. [:math:`kg/(s\,m\,m^3)`] is a reasonable situation.
.. tip::
Typical use cases for Dirichlet conditions in a Richards Model
include:
Datafile Structure
==================
* Height above a fixed water table at the lower boundary.
* Evaporative potential at upper boundary, if :math:`h_m < z_\text{wt}`,
where :math:`z_\text{wt}` is the height above the water table.
Boundary Segmentation
---------------------
::
**Transport Model**
Quantity: Total concentration :math:`C_t\,[\text{kg}\,\text{m}^{-d}]`
or concentration in the water phase
:math:`C_w\,[\text{kg}\,\text{m}^{-d}]`, depending on the value of
``concentration_type``. The integer :math:`d` denotes the spatial
dimension.
spatial_resolution_<position> <value_count> <values>...
Variables:
* ``type``: ``Dirichlet``
* ``value``: Quantity as specified above.
* ``concentration_type`` **(Transport only)**: Switch between ``total``
(:math:`C_t`) or ``water_phase`` (:math:`C_w`) concentration as
defined above.
In 2D, the spatial segmentation is fairly simple. The boundary is split into four parts, North, South, West and East. For each of these parts, we specify how many segmentation values will be stated, followed by the values themselves. The segmentation is applied along the respective spatial base vector (e.g. from West to East for the Northern and Southern boundaries).
.. option:: Neumann
.. note:: ``value_count = 0`` means that the respective boundary is one segment for which an explicit BC has to be specified.
A Neumann boundary condition determines the value of target quantity flux
at the boundary.
To split a northern boundary with a length of 3 m into three equidistant segments, we need to define
**Richards Model**
Quantity: Water flux :math:`\mathbf{j}_w \, [\text{ms}^{-1}]`.
::
Precipitation and evapotranspiration fluxes are typically measured
with respect to a flat surface. For modeling these fluxes, the
``horizontal_projection`` key is used, which scales the flux applied
to the boundary with its inclination with respect to the direction of
gravitational force,
spatial_resolution_north 2 1.0 2.0
.. math::
.. object:: No Flow Boundary
j_{N, \text{scaled}}
= \left| \mathbf{\hat{n}} \cdot \mathbf{\hat{g}} \right| j_N .
To apply a Neumann BC with flux :math:`j=0 \, \text{ms}^{-1}` to a boundary without any segmentation, set ``value_count = -1``. This boundary will **not** be considered in the `Boundary Condition Specification`_.
.. note:: Hydraulic conductivity decreases with water content. Evaporation
fluxes must not infinitely exceed the stable limit, or else the
solver will inevitably fail.
In 3D, every boundary is defined by two adjacent borders. By segmenting the borders, the boundary is split up into rectangles, for each of which a boundary condition has to be specified. To split a northern boundary of a cubic domain with an edge length of 2 m into four squares, we need to define
**Transport Model**
Quantity: Solute flux
:math:`\mathbf{j}_s \, [\text{kg}\,\text{m}^{-d+1}\,\text{s}^{-1}]`,
where :math:`d` indicates the spatial dimensions.
::
Variables:
* ``type``: ``Neumann``
* ``value``: Flux perpendicular to the surface :math:`j_N`, in the
quantities defined above. Fluxes into the domain are negative, fluxes
out of the domain positive.
* ``horizontal_projection`` **(Richards only)**: Boolean if the
actual boundary flux should be scaled with the surface inclination
against the direction of gravity.
spatial_resolution_north_fb 1 1.0
spatial_resolution_north_we 1 1.0
.. option:: Outflow (Transport only)
No Flow Boundaries are possible here as well. Notice that this definition has to be consistent for every boundary. DORiE will throw an error if you try to segment a border of one boundary if the other border is defined as No Flow Boundary.
An outflow boundary condition allows solute be transported throw the
boundary by the water flux. As solute concentration and water flux are
only modelled inside the domain, this effectively only allows the solute
to leave the domain and be discarded. The boundary condition value is an
additional solute flux for which all considerations of a Neumann boundary
condition apply (see above).
Number of Time Stamps
---------------------
::
Quantity: Solute flux
:math:`\mathbf{j}_s \, [\text{kg}\,\text{m}^{-d+1}\,\text{s}^{-1}]`, where
:math:`d` indicates the spatial dimensions.
number_BC_change_times <int>
The total solute flux through the boundary is then given by
Specify the number of time stamps for which BCs will be defined.
.. math::
.. note:: Every line is counted as one time stamp, even if two subsequent lines define BCs for the same time, as in the case of BC value interpolation.
j_s = \left| \mathbf{j}_s \cdot \mathbf{\hat{n}} \right| + j_N ,
where :math:`\mathbf{j}_s = C_w \mathbf{j}_w` is the solute flux at the
boundary, :math:`\mathbf{\hat{n}}` is the boundary unit normal vector and
:math:`j_N` is the given boundary condition ``value``, as defined below.
Boundary Condition Specification
--------------------------------
The boundary conditions have to be defined **for every segment** and **in every time stamp**. Boundary conditions and their respective values are separated by single whitespaces. All BC specifications for one time stamp have to be stated in the same line. BCs between adjacent borders are not interpolated and thus not steady.
These lines follow a simple grammar:
.. productionlist:: bc
bc_line: time { group }*
time: `float`
group: ( bc_type `float` )
bc_type: "neumann" | "dirichlet" | "outflow"
The boundary conditions defined here are parsed in the same order as the boundary segments have been specified. In 3D, the rectangular boundary segments are parsed in a tabular fashion, where columns run faster than rows. Columns are defined along the first direction specified in the `Boundary Segmentation`_, and rows are defined along the second direction.
.. figure:: /figures/man-bcfile-segm1.png
:width: 40 %
:align: left
Spatial segmentation of the northern boundary for the example stated in `Boundary Segmentation`_ (top view). ``x`` points towards the east-west direction and ``y`` towards the front-back direction. Red numbers indicate the order in which the boundary conditions for the respective segment have to be stated.
If ``boundary.interpolateBCvalues = true`` is invoked in the parameter file, subsequent BCs **of the same type** will be linearly interpolated. In order to change the BC type for a certain boundary segment, the respective time stamp has to be stated twice:
::
0 neumann -1e-6 [...]
2000 neumann -5e-6 [...]
2000 dirichlet 0.0 [...]
This will linearly interpolate the Neumann BC values for :math:`0 \leq t < 2000` between :math:`j(t=0) = -1 \cdot 10^{-6} \, \text{ms}^{-1}` and :math:`j(t=2000) = -5 \cdot 10^{-6} \, \text{ms}^{-1}`, and switch the BC type to Dirichlet at :math:`t=2000`. DORiE will throw an error if you choose subsequent time stamps which cannot be interpolated. Notice that the second line is syntactically valid for disabled interpolation as well, although it has no effect then.
Variables:
* ``type``: ``Outflow``
* ``value``: Flux perpendicular to the surface :math:`j_N`, as in
:option:`Neumann`. This flux is applied in addition to regular
seepage through the boundary. It is recommended to set this value to
0 (zero).
Example Files
=============
Simple Boundary Condition datafiles can be created with the command ``dorie create``.
Exemplary BC File for Infiltration (2D)
---------------------------------------
-------------
.. include:: /default_files/2d_infiltr.bcdat
:code: ini
DORiE provides a set of example files which can be placed into any directory
using the ``dorie create`` command of the
:ref:`Command Line Interface <man-cli-commands>`.
Exemplary BC File for Infiltration (3D)
---------------------------------------
Using the default mapping of a rectangular grid, the default boundary condition
file for the Richards model yields a strong infiltration flux at the upper
boundary and a water table at the lower boundary, while all other boundaries
are impermeable. The ``horizontal_projection`` parameter ensures that the given
value is the rainfall per unit area in case the surface is tilted or
irregularly shaped.
.. include:: /default_files/3d_infiltr.bcdat
:code: ini
.. literalinclude:: ../default_files/infiltration.yml
:language: yaml
Code Documentation
==================
The default boundary condition file for the Transport model yields a constant
concentration of solute at the upper boundary, similar to a homogeneous tracer
in the fluid. All other boundaries employ outflow conditions.
The readout of the boundary condition datafile and the handling of the associated data are managed by a single class.
.. literalinclude:: ../default_files/solute.yml
:language: yaml
.. doxygenclass:: Dune::Dorie::RectangularGrid
:members:
:private-members:
:undoc-members:
.. _YAML: https://gettaurus.org/docs/YAMLTutorial/
......@@ -68,6 +68,7 @@ successful. You can deactivate the ``venv`` at any time by executing
You are now ready to use the DORiE Command Line Interface!
.. _man-cli-commands:
CLI Commands
============
......
#ifndef DUNE_DORIE_COMMON_BOUNDARY_CONDITION_BASE_HH
#define DUNE_DORIE_COMMON_BOUNDARY_CONDITION_BASE_HH