From 4225d1c5a61f9a271abdc50c245d617c96aa2afd Mon Sep 17 00:00:00 2001 From: Florian Zill <florian.zill@ufz.de> Date: Fri, 23 Aug 2019 15:28:10 +0200 Subject: [PATCH] [HM] specific storage is now calculated added specific gas constant added Fluid compressibility added Fluid type added bbulk modulus removed specific storage --- .../t_fluid_compressibility.md | 1 + .../process/HYDRO_MECHANICS/t_fluid_type.md | 1 + .../t_specific_gas_constant.md | 1 + .../CreateHydroMechanicsProcess.cpp | 49 +++++++++++----- .../HydroMechanics/HydroMechanicsFEM-impl.h | 40 ++++++++++--- .../HydroMechanicsProcessData.h | 56 ++++++++++++++++++- 6 files changed, 122 insertions(+), 26 deletions(-) create mode 100644 Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_fluid_compressibility.md create mode 100644 Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_fluid_type.md create mode 100644 Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_specific_gas_constant.md diff --git a/Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_fluid_compressibility.md b/Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_fluid_compressibility.md new file mode 100644 index 00000000000..8601db2de06 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_fluid_compressibility.md @@ -0,0 +1 @@ +\copydoc ProcessLib::HydroMechanics::HydroMechanicsProcessData::fluid_compressibility diff --git a/Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_fluid_type.md b/Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_fluid_type.md new file mode 100644 index 00000000000..24e00605c57 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_fluid_type.md @@ -0,0 +1 @@ +\copydoc ProcessLib::HydroMechanics::HydroMechanicsProcessData::fluid_type diff --git a/Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_specific_gas_constant.md b/Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_specific_gas_constant.md new file mode 100644 index 00000000000..45897fcdfa7 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/HYDRO_MECHANICS/t_specific_gas_constant.md @@ -0,0 +1 @@ +\copydoc ProcessLib::HydroMechanics::HydroMechanicsProcessData::specific_gas_constant diff --git a/ProcessLib/HydroMechanics/CreateHydroMechanicsProcess.cpp b/ProcessLib/HydroMechanics/CreateHydroMechanicsProcess.cpp index 80b00d24701..e937977f35d 100644 --- a/ProcessLib/HydroMechanics/CreateHydroMechanicsProcess.cpp +++ b/ProcessLib/HydroMechanics/CreateHydroMechanicsProcess.cpp @@ -117,15 +117,6 @@ std::unique_ptr<Process> createHydroMechanicsProcess( DBUG("Use '%s' as intrinsic conductivity parameter.", intrinsic_permeability.name.c_str()); - // Storage coefficient - auto& specific_storage = ParameterLib::findParameter<double>( - config, - //! \ogs_file_param_special{prj__processes__process__HYDRO_MECHANICS__specific_storage} - "specific_storage", parameters, 1, &mesh); - - DBUG("Use '%s' as storage coefficient parameter.", - specific_storage.name.c_str()); - // Fluid viscosity auto& fluid_viscosity = ParameterLib::findParameter<double>( config, @@ -183,18 +174,46 @@ std::unique_ptr<Process> createHydroMechanicsProcess( } // Reference temperature - const auto& reference_temperature = + double const reference_temperature = //! \ogs_file_param{prj__processes__process__HYDRO_MECHANICS__reference_temperature} config.getConfigParameter<double>( "reference_temperature", std::numeric_limits<double>::quiet_NaN()); + DBUG("Use 'reference_temperature' as reference temperature."); + + //Specific gas constant + double const specific_gas_constant = + //! \ogs_file_param{prj__processes__process__HYDRO_MECHANICS__specific_gas_constant} + config.getConfigParameter<double>( + "specific_gas_constant", std::numeric_limits<double>::quiet_NaN()); + DBUG("Use 'specific_gas_constant' as specific gas constant."); + + // Fluid compressibility + double const fluid_compressibility = + //! \ogs_file_param{prj__processes__process__HYDRO_MECHANICS__fluid_compressibility} + config.getConfigParameter<double>( + "fluid_compressibility", std::numeric_limits<double>::quiet_NaN()); + DBUG("Use 'fluid_compressibility' as fluid compressibility parameter."); + + auto const fluid_type = + //! \ogs_file_param{prj__processes__process__HYDRO_MECHANICS__fluid_type} + FluidType::strToFluidType( + config.getConfigParameter<std::string>("fluid_type")); + DBUG("Use 'fluid_type' as fluid type parameter."); + + if (FluidType::checkRequiredParams(fluid_type, fluid_compressibility, + reference_temperature, specific_gas_constant) == false) + { + OGS_FATAL(FluidType::getErrorMsg(fluid_type)); + } HydroMechanicsProcessData<DisplacementDim> process_data{ materialIDs(mesh), std::move(solid_constitutive_relations), - intrinsic_permeability, specific_storage, - fluid_viscosity, fluid_density, - biot_coefficient, porosity, - solid_density, specific_body_force, - reference_temperature}; + intrinsic_permeability, fluid_viscosity, + fluid_density, biot_coefficient, + porosity, solid_density, + specific_body_force, fluid_compressibility, + reference_temperature, specific_gas_constant, + fluid_type}; SecondaryVariableCollection secondary_variables; diff --git a/ProcessLib/HydroMechanics/HydroMechanicsFEM-impl.h b/ProcessLib/HydroMechanics/HydroMechanicsFEM-impl.h index 457acd7770b..bc6fb267bae 100644 --- a/ProcessLib/HydroMechanics/HydroMechanicsFEM-impl.h +++ b/ProcessLib/HydroMechanics/HydroMechanicsFEM-impl.h @@ -164,7 +164,11 @@ void HydroMechanicsLocalAssembler<ShapeFunctionDisplacement, pressure_size, displacement_size>::Zero(pressure_size, displacement_size); + MaterialLib::Solids::MechanicsBase<DisplacementDim> const& solid_material = + *_process_data.solid_materials[0]; + double const& dt = _process_data.dt; + double const T_ref = _process_data.reference_temperature; ParameterLib::SpatialPosition x_position; x_position.setElementID(_element.getID()); @@ -197,13 +201,19 @@ void HydroMechanicsLocalAssembler<ShapeFunctionDisplacement, auto& eps = _ip_data[ip].eps; auto const& sigma_eff = _ip_data[ip].sigma_eff; - double const S = _process_data.specific_storage(t, x_position)[0]; double const K_over_mu = _process_data.intrinsic_permeability(t, x_position)[0] / _process_data.fluid_viscosity(t, x_position)[0]; auto const alpha = _process_data.biot_coefficient(t, x_position)[0]; + auto const K_S = solid_material.getBulkModulus(t, x_position); auto const rho_sr = _process_data.solid_density(t, x_position)[0]; - auto const rho_fr = _process_data.fluid_density(t, x_position)[0]; + // TODO (FZill) get fluid properties from GPML + double const p_fr = + (_process_data.fluid_type == FluidType::Fluid_Type::IDEAL_GAS) + ? N_p.dot(p) + : std::numeric_limits<double>::quiet_NaN(); + double const rho_fr = _process_data.getFluidDensity(t, x_position, p_fr); + double const beta_p = _process_data.getFluidCompressibility(p_fr); auto const porosity = _process_data.porosity(t, x_position)[0]; auto const& b = _process_data.specific_body_force; auto const& identity2 = MathLib::KelvinVector::Invariants< @@ -215,8 +225,8 @@ void HydroMechanicsLocalAssembler<ShapeFunctionDisplacement, // eps.noalias() = B * u; - auto C = _ip_data[ip].updateConstitutiveRelation( - t, x_position, dt, u, _process_data.reference_temperature); + auto C = + _ip_data[ip].updateConstitutiveRelation(t, x_position, dt, u, T_ref); local_Jac .template block<displacement_size, displacement_size>( @@ -239,7 +249,9 @@ void HydroMechanicsLocalAssembler<ShapeFunctionDisplacement, laplace_p.noalias() += rho_fr * dNdx_p.transpose() * K_over_mu * dNdx_p * w; - storage_p.noalias() += rho_fr * N_p.transpose() * S * N_p * w; + storage_p.noalias() += + rho_fr * N_p.transpose() * N_p * w * + ((alpha - porosity) * (1.0 - alpha) / K_S + porosity * beta_p); local_rhs.template segment<pressure_size>(pressure_index).noalias() += dNdx_p.transpose() * rho_fr * rho_fr * K_over_mu * b * w; @@ -373,6 +385,9 @@ void HydroMechanicsLocalAssembler<ShapeFunctionDisplacement, ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size, pressure_size); + MaterialLib::Solids::MechanicsBase<DisplacementDim> const& solid_material = + *_process_data.solid_materials[0]; + double const& dt = _process_data.dt; ParameterLib::SpatialPosition x_position; @@ -390,16 +405,25 @@ void HydroMechanicsLocalAssembler<ShapeFunctionDisplacement, auto const& N_p = _ip_data[ip].N_p; auto const& dNdx_p = _ip_data[ip].dNdx_p; - double const S = _process_data.specific_storage(t, x_position)[0]; double const K_over_mu = _process_data.intrinsic_permeability(t, x_position)[0] / _process_data.fluid_viscosity(t, x_position)[0]; auto const alpha_b = _process_data.biot_coefficient(t, x_position)[0]; - auto const rho_fr = _process_data.fluid_density(t, x_position)[0]; + // TODO (FZill) get fluid properties from GPML + double const p_fr = + (_process_data.fluid_type == FluidType::Fluid_Type::IDEAL_GAS) + ? N_p.dot(p) + : std::numeric_limits<double>::quiet_NaN(); + double const rho_fr = _process_data.getFluidDensity(t, x_position, p_fr); + double const beta_p = _process_data.getFluidCompressibility(p_fr); + auto const porosity = _process_data.porosity(t, x_position)[0]; + auto const K_S = solid_material.getBulkModulus(t, x_position); laplace.noalias() += dNdx_p.transpose() * K_over_mu * dNdx_p * w; - mass.noalias() += N_p.transpose() * S * N_p * w; + mass.noalias() += + N_p.transpose() * N_p * w * + ((alpha_b - porosity) * (1.0 - alpha_b) / K_S + porosity * beta_p); auto const& b = _process_data.specific_body_force; local_rhs.noalias() += dNdx_p.transpose() * rho_fr * K_over_mu * b * w; diff --git a/ProcessLib/HydroMechanics/HydroMechanicsProcessData.h b/ProcessLib/HydroMechanics/HydroMechanicsProcessData.h index 7299cb661e6..9bb3ff3ff0c 100644 --- a/ProcessLib/HydroMechanics/HydroMechanicsProcessData.h +++ b/ProcessLib/HydroMechanics/HydroMechanicsProcessData.h @@ -10,6 +10,7 @@ #pragma once #include "ParameterLib/Parameter.h" +#include "MaterialLib/Fluid/FluidType/FluidType.h" #include <memory> #include <utility> @@ -42,9 +43,6 @@ struct HydroMechanicsProcessData /// Permeability of the solid. A scalar quantity, /// ParameterLib::Parameter<double>. ParameterLib::Parameter<double> const& intrinsic_permeability; - /// Volumetric average specific storage of the solid and fluid phases. - /// A scalar quantity, ParameterLib::Parameter<double>. - ParameterLib::Parameter<double> const& specific_storage; /// Fluid's viscosity. A scalar quantity, ParameterLib::Parameter<double>. ParameterLib::Parameter<double> const& fluid_viscosity; /// Fluid's density. A scalar quantity, ParameterLib::Parameter<double>. @@ -60,9 +58,61 @@ struct HydroMechanicsProcessData /// It is usually used to apply gravitational forces. /// A vector of displacement dimension's length. Eigen::Matrix<double, DisplacementDim, 1> const specific_body_force; + + /// Fluid's compressibility. A scalar quantity. + /// Only used for compressible_fluid fluid_type + double const fluid_compressibility = + std::numeric_limits<double>::quiet_NaN(); + + /// Reference Temperature. A scalar quantity. + /// Only used for ideal_gas fluid_type double const reference_temperature = std::numeric_limits<double>::quiet_NaN(); + /// Specific gas constant. A scalar quantity. + /// Only used for ideal_gas fluid_type + double const specific_gas_constant = + std::numeric_limits<double>::quiet_NaN(); + + /// Fluid type. Enumerator with possible values: + /// incompressible_fluid, compressible_fluid, ideal_gas + FluidType::Fluid_Type const fluid_type; + + /// will be removed after linking with MPL + double getFluidDensity( + double const& t, ParameterLib::SpatialPosition const& x_position, + double const& p_fr) + { + if (fluid_type == FluidType::Fluid_Type::INCOMPRESSIBLE_FLUID || + fluid_type == FluidType::Fluid_Type::COMPRESSIBLE_FLUID) + { + return fluid_density(t, x_position)[0]; + } + if (fluid_type == FluidType::Fluid_Type::IDEAL_GAS) + { + return p_fr / (specific_gas_constant * reference_temperature); + } + OGS_FATAL("unknown fluid type %d", static_cast<int> (fluid_type)); + } + + /// will be removed after linking with MPL + double getFluidCompressibility(double const& p_fr) + { + if (fluid_type == FluidType::Fluid_Type::INCOMPRESSIBLE_FLUID) + { + return 0.0; + } + if (fluid_type == FluidType::Fluid_Type::COMPRESSIBLE_FLUID) + { + return fluid_compressibility; + } + if (fluid_type == FluidType::Fluid_Type::IDEAL_GAS) + { + return 1.0 / p_fr; + } + OGS_FATAL("unknown fluid type %d", static_cast<int> (fluid_type)); + } + MeshLib::PropertyVector<double>* pressure_interpolated = nullptr; double dt = std::numeric_limits<double>::quiet_NaN(); double t = std::numeric_limits<double>::quiet_NaN(); -- GitLab