From 8a455bb79b09f9e71ddfa87e8da5a5e1a27c7260 Mon Sep 17 00:00:00 2001 From: Norbert Grunwald <Norbert.Grunwald@ufz.de> Date: Mon, 9 Nov 2020 14:13:13 +0100 Subject: [PATCH] <MPL> add saturationExponential property --- MaterialLib/MPL/CreateProperty.cpp | 4 + .../CreateSaturationExponential.cpp | 45 +++++++++ .../CreateSaturationExponential.h | 29 ++++++ .../SaturationExponential.cpp | 94 +++++++++++++++++++ .../SaturationExponential.h | 70 ++++++++++++++ MaterialLib/MPL/Properties/CreateProperties.h | 1 + MaterialLib/MPL/Properties/Properties.h | 1 + 7 files changed, 244 insertions(+) create mode 100644 MaterialLib/MPL/Properties/CapillaryPressureSaturation/CreateSaturationExponential.cpp create mode 100644 MaterialLib/MPL/Properties/CapillaryPressureSaturation/CreateSaturationExponential.h create mode 100644 MaterialLib/MPL/Properties/CapillaryPressureSaturation/SaturationExponential.cpp create mode 100644 MaterialLib/MPL/Properties/CapillaryPressureSaturation/SaturationExponential.h diff --git a/MaterialLib/MPL/CreateProperty.cpp b/MaterialLib/MPL/CreateProperty.cpp index 049f4a7e1a2..082de71d9be 100644 --- a/MaterialLib/MPL/CreateProperty.cpp +++ b/MaterialLib/MPL/CreateProperty.cpp @@ -157,6 +157,10 @@ std::unique_ptr<MaterialPropertyLib::Property> createProperty( return createRelPermLiakopoulos(config); } + if (boost::iequals(property_type, "SaturationExponential")) + { + return createSaturationExponential(config); + } if (boost::iequals(property_type, "SaturationVanGenuchten")) { return createSaturationVanGenuchten(config); diff --git a/MaterialLib/MPL/Properties/CapillaryPressureSaturation/CreateSaturationExponential.cpp b/MaterialLib/MPL/Properties/CapillaryPressureSaturation/CreateSaturationExponential.cpp new file mode 100644 index 00000000000..f0778c81c38 --- /dev/null +++ b/MaterialLib/MPL/Properties/CapillaryPressureSaturation/CreateSaturationExponential.cpp @@ -0,0 +1,45 @@ +/** + * \file + * \copyright + * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#include "BaseLib/ConfigTree.h" +#include "SaturationExponential.h" + +namespace MaterialPropertyLib +{ +std::unique_ptr<SaturationExponential> createSaturationExponential( + BaseLib::ConfigTree const& config) +{ + //! \ogs_file_param{properties__property__type} + config.checkConfigParameter("type", "SaturationExponential"); + + // Second access for storage. + //! \ogs_file_param{properties__property__name} + auto property_name = config.peekConfigParameter<std::string>("name"); + + DBUG("Create SaturationExponential medium property {:s}.", property_name); + + auto const residual_liquid_saturation = + //! \ogs_file_param{properties__property__SaturationExponential__residual_liquid_saturation} + config.getConfigParameter<double>("residual_liquid_saturation"); + auto const residual_gas_saturation = + //! \ogs_file_param{properties__property__SaturationExponential__residual_gas_saturation} + config.getConfigParameter<double>("residual_gas_saturation"); + auto const p_cap_ref = + //! \ogs_file_param{properties__property__SaturationExponential__reference_capillary_pressure} + config.getConfigParameter<double>("reference_capillary_pressure"); + auto const exponent = + //! \ogs_file_param{properties__property__SaturationExponential__exponent} + config.getConfigParameter<double>("exponent"); + + return std::make_unique<SaturationExponential>( + std::move(property_name), residual_liquid_saturation, + residual_gas_saturation, p_cap_ref, exponent); +} +} // namespace MaterialPropertyLib diff --git a/MaterialLib/MPL/Properties/CapillaryPressureSaturation/CreateSaturationExponential.h b/MaterialLib/MPL/Properties/CapillaryPressureSaturation/CreateSaturationExponential.h new file mode 100644 index 00000000000..2e00abdee2f --- /dev/null +++ b/MaterialLib/MPL/Properties/CapillaryPressureSaturation/CreateSaturationExponential.h @@ -0,0 +1,29 @@ +/** + * \file + * \copyright + * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#pragma once + +#include <memory> + +namespace BaseLib +{ +class ConfigTree; +} + +namespace MaterialPropertyLib +{ +class SaturationExponential; +} + +namespace MaterialPropertyLib +{ +std::unique_ptr<SaturationExponential> createSaturationExponential( + BaseLib::ConfigTree const& config); +} // namespace MaterialPropertyLib diff --git a/MaterialLib/MPL/Properties/CapillaryPressureSaturation/SaturationExponential.cpp b/MaterialLib/MPL/Properties/CapillaryPressureSaturation/SaturationExponential.cpp new file mode 100644 index 00000000000..9e35916b4b1 --- /dev/null +++ b/MaterialLib/MPL/Properties/CapillaryPressureSaturation/SaturationExponential.cpp @@ -0,0 +1,94 @@ +/** + * \file + * \author Norbert Grunwald + * \date 27.06.2018 + * \brief + * + * \copyright + * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#include "SaturationExponential.h" + +#include <algorithm> +#include <cmath> + +#include "MaterialLib/MPL/Medium.h" +#include "MathLib/MathTools.h" + +namespace MaterialPropertyLib +{ +SaturationExponential::SaturationExponential( + std::string name, + const double residual_liquid_saturation, + const double residual_gas_saturation, + const double p_cap_ref, + const double exponent) + : residual_liquid_saturation_(residual_liquid_saturation), + residual_gas_saturation_(residual_gas_saturation), + p_cap_ref_(p_cap_ref), + exponent_(exponent) +{ + name_ = std::move(name); + if (p_cap_ref_ <= 0.) + { + OGS_FATAL( + "Reference capillary pressure must be positive in " + "MPL::SaturationExponential."); + } +}; + +PropertyDataType SaturationExponential::value( + VariableArray const& variable_array, + ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/, + double const /*dt*/) const +{ + const double p_cap = std::get<double>( + variable_array[static_cast<int>(Variable::capillary_pressure)]); + + const double s_res = residual_liquid_saturation_; + const double s_max = 1. - residual_gas_saturation_; + + const double pc = std::clamp(p_cap, 0., p_cap_ref_); + const double s_e = 1. - std::pow(pc / p_cap_ref_, exponent_); + return s_e * (s_max - s_res) + s_res; +} + +PropertyDataType SaturationExponential::dValue( + VariableArray const& variable_array, Variable const primary_variable, + ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/, + double const /*dt*/) const +{ + (void)primary_variable; + assert((primary_variable == Variable::capillary_pressure) && + "SaturationExponential::dValue is implemented for derivatives with " + "respect to capillary pressure only."); + + const double p_cap = std::get<double>( + variable_array[static_cast<int>(Variable::capillary_pressure)]); + + const double s_res = residual_liquid_saturation_; + const double s_max = 1. - residual_gas_saturation_; + + if ((p_cap > p_cap_ref_) || (p_cap <= 0.)) + { + return 0.; + } + return (exponent_ / p_cap) * (s_res - s_max) * + std::pow(p_cap / p_cap_ref_, exponent_); +} + +PropertyDataType SaturationExponential::d2Value( + VariableArray const& /*variable_array*/, + Variable const /*primary_variable1*/, Variable const /*primary_variable2*/, + ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/, + double const /*dt*/) const +{ + OGS_FATAL("SaturationExponential::d2Value() is not implemented."); +} + +} // namespace MaterialPropertyLib diff --git a/MaterialLib/MPL/Properties/CapillaryPressureSaturation/SaturationExponential.h b/MaterialLib/MPL/Properties/CapillaryPressureSaturation/SaturationExponential.h new file mode 100644 index 00000000000..3f1063d687f --- /dev/null +++ b/MaterialLib/MPL/Properties/CapillaryPressureSaturation/SaturationExponential.h @@ -0,0 +1,70 @@ +/** + * \file + * \author Norbert Grunwald + * \date 27.06.2018 + * \brief + * + * \copyright + * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ +#pragma once + +#include <limits> + +#include "MaterialLib/MPL/Property.h" + +namespace MaterialPropertyLib +{ +/** + * \brief A simplistic soil characteristics function + * \details This property must be a medium property, it + * computes the saturation of the wetting phase as function + * of capillary pressure. + */ +class SaturationExponential final : public Property +{ +private: + const double residual_liquid_saturation_; + const double residual_gas_saturation_; + const double p_cap_ref_; + const double exponent_; + +public: + SaturationExponential(std::string name, + const double residual_liquid_saturation, + const double residual_gas_saturation, + const double p_cap_ref, const double exponent); + + void checkScale() const override + { + if (!std::holds_alternative<Medium*>(scale_)) + { + OGS_FATAL( + "The property 'SaturationExponential' is implemented on the " + "'media' scale only."); + } + } + + /// Those methods override the base class implementations and + /// actually compute and set the property values_ and dValues_. + PropertyDataType value(VariableArray const& variable_array, + ParameterLib::SpatialPosition const& /*pos*/, + double const /*t*/, + double const /*dt*/) const override; + PropertyDataType dValue(VariableArray const& variable_array, + Variable const primary_variable, + ParameterLib::SpatialPosition const& /*pos*/, + double const /*t*/, + double const /*dt*/) const override; + PropertyDataType d2Value(VariableArray const& variable_array, + Variable const /*primary_variable1*/, + Variable const /*primary_variable2*/, + ParameterLib::SpatialPosition const& /*pos*/, + double const /*t*/, + double const /*dt*/) const override; +}; +} // namespace MaterialPropertyLib diff --git a/MaterialLib/MPL/Properties/CreateProperties.h b/MaterialLib/MPL/Properties/CreateProperties.h index 7f177a085f4..4c62b2242dd 100644 --- a/MaterialLib/MPL/Properties/CreateProperties.h +++ b/MaterialLib/MPL/Properties/CreateProperties.h @@ -15,6 +15,7 @@ #include "CapillaryPressureSaturation/CreateCapillaryPressureVanGenuchten.h" #include "CapillaryPressureSaturation/CreateSaturationBrooksCorey.h" #include "CapillaryPressureSaturation/CreateSaturationLiakopoulos.h" +#include "CapillaryPressureSaturation/CreateSaturationExponential.h" #include "CapillaryPressureSaturation/CreateSaturationVanGenuchten.h" #include "CreateAverageMolarMass.h" #include "CreateBishopsPowerLaw.h" diff --git a/MaterialLib/MPL/Properties/Properties.h b/MaterialLib/MPL/Properties/Properties.h index ee5a30636d4..f1ec5467d48 100644 --- a/MaterialLib/MPL/Properties/Properties.h +++ b/MaterialLib/MPL/Properties/Properties.h @@ -16,6 +16,7 @@ #include "BishopsSaturationCutoff.h" #include "CapillaryPressureSaturation/SaturationBrooksCorey.h" #include "CapillaryPressureSaturation/SaturationLiakopoulos.h" +#include "CapillaryPressureSaturation/SaturationExponential.h" #include "CapillaryPressureSaturation/SaturationVanGenuchten.h" #include "ClausiusClapeyron.h" #include "Constant.h" -- GitLab