diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/c_RICHARDS_FLOW.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/c_RICHARDS_FLOW.md index 576add64edccf5d980a0ff86143dc43a7109a788..f5925e17d6fb4fd5bcaa304e814d1bf3f53731c8 100644 --- a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/c_RICHARDS_FLOW.md +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/c_RICHARDS_FLOW.md @@ -1 +1 @@ -\ogs_missing_documentation +\copydoc ProcessLib::RichardsFlow::RichardsFlowProcess diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/fluid/i_fluid.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/fluid/i_fluid.md new file mode 100644 index 0000000000000000000000000000000000000000..00aef4b95e01a85c9fb21ee4e2f36860cefd7dc1 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/fluid/i_fluid.md @@ -0,0 +1 @@ +Defines fluid properties. diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/i_material_property.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/i_material_property.md new file mode 100644 index 0000000000000000000000000000000000000000..c0c96b339623410ba707bd6ddf4a2037c07162d5 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/i_material_property.md @@ -0,0 +1 @@ +A tag for material properties of the RichardsFlow process. diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/i_porous_medium.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/i_porous_medium.md new file mode 100644 index 0000000000000000000000000000000000000000..0ff6eac587d8f6af9cd9f8087fcdb7ab184d6bc7 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/i_porous_medium.md @@ -0,0 +1,13 @@ +A tag for the properties of porous media, which contains nested tags for +different porous media, which are distinguished by material IDs. For example + +``` + <porous_medium> + <porous_medium id="0"> + ... + </porous_medium> + <porous_medium id="1"> + ... + </porous_medium> + </porous_medium> +``` \ No newline at end of file diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/a_id.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/a_id.md new file mode 100644 index 0000000000000000000000000000000000000000..c1dae9f80b40a7c5ba5eb2fc7fae385bf250a298 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/a_id.md @@ -0,0 +1,2 @@ +It specifies the material ID of a porous medium. The material IDs of elements +must be given in the mesh's cell data array "MaterialIDs". diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/i_porous_medium.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/i_porous_medium.md new file mode 100644 index 0000000000000000000000000000000000000000..bb330dc056ceff8400e948dfb52a53fb0f44252a --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/i_porous_medium.md @@ -0,0 +1 @@ +A tag for the properties of a porous medium with material ID. \ No newline at end of file diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_capillary_pressure.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_capillary_pressure.md new file mode 100644 index 0000000000000000000000000000000000000000..19d854870d0c3537197cc8edb349b03503fcbede --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_capillary_pressure.md @@ -0,0 +1 @@ +Capillary pressure model. diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_permeability.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_permeability.md new file mode 100644 index 0000000000000000000000000000000000000000..075c8a48fde6b9a1d7682d9cc08e6bcaa9feeb93 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_permeability.md @@ -0,0 +1 @@ +A tag for the relative permeability model of a porous medium. \ No newline at end of file diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_porosity.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_porosity.md new file mode 100644 index 0000000000000000000000000000000000000000..d90fcba994c498eb7f7c82b6052cf4619ef7735b --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_porosity.md @@ -0,0 +1 @@ +A tag for the porosity model of a porous medium. \ No newline at end of file diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_relative_permeability.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_relative_permeability.md new file mode 100644 index 0000000000000000000000000000000000000000..fd2a51343fb9e4a7a8ce38bdc88c31f400c1b7e7 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_relative_permeability.md @@ -0,0 +1 @@ +A tag for the relative permeability model. diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_storage.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_storage.md new file mode 100644 index 0000000000000000000000000000000000000000..756a75cbc74b625cca84e3b6b15dcc29b36026b5 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/material_property/porous_medium/porous_medium/t_storage.md @@ -0,0 +1 @@ +A tag for the storage model of a porous medium. \ No newline at end of file diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/process_variables/i_process_variables.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/process_variables/i_process_variables.md index 576add64edccf5d980a0ff86143dc43a7109a788..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/process_variables/i_process_variables.md +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/process_variables/i_process_variables.md @@ -1 +0,0 @@ -\ogs_missing_documentation diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/process_variables/t_process_variable.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/process_variables/t_process_variable.md index 576add64edccf5d980a0ff86143dc43a7109a788..b41ba4a237742a7e452d9f8a769a412d3086c487 100644 --- a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/process_variables/t_process_variable.md +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/process_variables/t_process_variable.md @@ -1 +1 @@ -\ogs_missing_documentation +A tag for the primary variable in RichardsFlow Process. In this implementation, fluid pressure is used as primary variable. diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_intrinsic_permeability.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_intrinsic_permeability.md deleted file mode 100644 index 576add64edccf5d980a0ff86143dc43a7109a788..0000000000000000000000000000000000000000 --- a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_intrinsic_permeability.md +++ /dev/null @@ -1 +0,0 @@ -\ogs_missing_documentation diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_mass_lumping.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_mass_lumping.md index 576add64edccf5d980a0ff86143dc43a7109a788..b7844df80113ac416e571e335b34b301474f9835 100644 --- a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_mass_lumping.md +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_mass_lumping.md @@ -1 +1 @@ -\ogs_missing_documentation +A tag for enabling mass-lumping scheme diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_porosity.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_porosity.md deleted file mode 100644 index 576add64edccf5d980a0ff86143dc43a7109a788..0000000000000000000000000000000000000000 --- a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_porosity.md +++ /dev/null @@ -1 +0,0 @@ -\ogs_missing_documentation diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_specific_body_force.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_specific_body_force.md index 576add64edccf5d980a0ff86143dc43a7109a788..ed337a7b8e0a63e758207f44be45ffead89e5177 100644 --- a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_specific_body_force.md +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_specific_body_force.md @@ -1 +1 @@ -\ogs_missing_documentation +Specific body forces applied to solid and fluid. It is usually used to apply gravitational forces. diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_storage.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_storage.md deleted file mode 100644 index 576add64edccf5d980a0ff86143dc43a7109a788..0000000000000000000000000000000000000000 --- a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_storage.md +++ /dev/null @@ -1 +0,0 @@ -\ogs_missing_documentation diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_temperature.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_temperature.md new file mode 100644 index 0000000000000000000000000000000000000000..a41a95c52ff9cd3047303ca8f4f5f21e9ea57da7 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_temperature.md @@ -0,0 +1,2 @@ +An input of a reference temperature (K) for RichardsFlow process. +It is fixed to be constant for the simulation due to an isothermal assumption. diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_viscosity.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_viscosity.md deleted file mode 100644 index 576add64edccf5d980a0ff86143dc43a7109a788..0000000000000000000000000000000000000000 --- a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_viscosity.md +++ /dev/null @@ -1 +0,0 @@ -\ogs_missing_documentation diff --git a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_water_density.md b/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_water_density.md deleted file mode 100644 index 576add64edccf5d980a0ff86143dc43a7109a788..0000000000000000000000000000000000000000 --- a/Documentation/ProjectFile/prj/processes/process/RICHARDS_FLOW/t_water_density.md +++ /dev/null @@ -1 +0,0 @@ -\ogs_missing_documentation diff --git a/ProcessLib/RichardsFlow/CreateRichardsFlowMaterialProperties.cpp b/ProcessLib/RichardsFlow/CreateRichardsFlowMaterialProperties.cpp new file mode 100644 index 0000000000000000000000000000000000000000..da3485782c507565f231676c2075874dc2770ab8 --- /dev/null +++ b/ProcessLib/RichardsFlow/CreateRichardsFlowMaterialProperties.cpp @@ -0,0 +1,117 @@ +/** + * \copyright + * Copyright (c) 2012-2017, 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 "CreateRichardsFlowMaterialProperties.h" + +#include <logog/include/logog.hpp> + +#include "BaseLib/reorderVector.h" +#include "MaterialLib/Fluid/FluidProperty.h" +#include "MaterialLib/Fluid/FluidProperties/CreateFluidProperties.h" +#include "MaterialLib/PorousMedium/Porosity/Porosity.h" +#include "MaterialLib/PorousMedium/Storage/Storage.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/CapillaryPressure/CapillaryPressureSaturation.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/CapillaryPressure/CreateCapillaryPressureModel.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/RelativePermeability/CreateRelativePermeabilityModel.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/RelativePermeability/RelativePermeability.h" +#include "MathLib/InterpolationAlgorithms/PiecewiseLinearInterpolation.h" +#include "MeshLib/Mesh.h" +#include "MeshLib/PropertyVector.h" +#include "ProcessLib/Parameter/Parameter.h" +#include "ProcessLib/Parameter/SpatialPosition.h" + +#include "RichardsFlowMaterialProperties.h" + +namespace ProcessLib +{ +namespace RichardsFlow +{ +std::unique_ptr<RichardsFlowMaterialProperties> +createRichardsFlowMaterialProperties( + BaseLib::ConfigTree const& config, + boost::optional<MeshLib::PropertyVector<int> const&> + material_ids) +{ + DBUG("Reading material properties of Richards flow process."); + + //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__material_property__fluid} + auto const& fluid_config = config.getConfigSubtree("fluid"); + auto fluid_properties = + MaterialLib::Fluid::createFluidProperties(fluid_config); + + // Get porous properties + std::vector<int> mat_ids; + std::vector<int> mat_krel_ids; + std::vector<Eigen::MatrixXd> intrinsic_permeability_models; + std::vector<std::unique_ptr<MaterialLib::PorousMedium::Porosity>> + porosity_models; + std::vector<std::unique_ptr<MaterialLib::PorousMedium::Storage>> + storage_models; + std::vector< + std::unique_ptr<MaterialLib::PorousMedium::CapillaryPressureSaturation>> + capillary_pressure_models; + std::vector< + std::unique_ptr<MaterialLib::PorousMedium::RelativePermeability>> + relative_permeability_models; + + //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__material_property__porous_medium} + auto const& poro_config = config.getConfigSubtree("porous_medium"); + //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__material_property__porous_medium__porous_medium} + for (auto const& conf : poro_config.getConfigSubtreeList("porous_medium")) + { + //! \ogs_file_attr{prj__processes__process__RICHARDS_FLOW__material_property__porous_medium__porous_medium__id} + auto const id = conf.getConfigAttributeOptional<int>("id"); + mat_ids.push_back(*id); + + //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__material_property__porous_medium__porous_medium__permeability} + auto const& permeability_conf = conf.getConfigSubtree("permeability"); + intrinsic_permeability_models.emplace_back( + MaterialLib::PorousMedium::createPermeabilityModel( + permeability_conf)); + + //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__material_property__porous_medium__porous_medium__porosity} + auto const& porosity_conf = conf.getConfigSubtree("porosity"); + auto n = MaterialLib::PorousMedium::createPorosityModel(porosity_conf); + porosity_models.emplace_back(std::move(n)); + + //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__material_property__porous_medium__porous_medium__storage} + auto const& storage_conf = conf.getConfigSubtree("storage"); + auto beta = MaterialLib::PorousMedium::createStorageModel(storage_conf); + storage_models.emplace_back(std::move(beta)); + + auto const& capillary_pressure_conf = + //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__material_property__porous_medium__porous_medium__capillary_pressure} + conf.getConfigSubtree("capillary_pressure"); + auto pc = MaterialLib::PorousMedium::createCapillaryPressureModel( + capillary_pressure_conf); + capillary_pressure_models.emplace_back(std::move(pc)); + + auto const& krel_config = + //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__material_property__porous_medium__porous_medium__relative_permeability} + conf.getConfigSubtree("relative_permeability"); + auto krel = MaterialLib::PorousMedium::createRelativePermeabilityModel( + krel_config); + relative_permeability_models.emplace_back(std::move(krel)); + } + + BaseLib::reorderVector(intrinsic_permeability_models, mat_ids); + BaseLib::reorderVector(porosity_models, mat_ids); + BaseLib::reorderVector(storage_models, mat_ids); + + return std::unique_ptr<RichardsFlowMaterialProperties>{ + new RichardsFlowMaterialProperties{ + material_ids, std::move(fluid_properties), + std::move(intrinsic_permeability_models), + std::move(porosity_models), std::move(storage_models), + std::move(capillary_pressure_models), + std::move(relative_permeability_models)}}; +} + +} // end namespace +} // end namespace diff --git a/ProcessLib/RichardsFlow/CreateRichardsFlowMaterialProperties.h b/ProcessLib/RichardsFlow/CreateRichardsFlowMaterialProperties.h new file mode 100644 index 0000000000000000000000000000000000000000..f069f286f291ef3991ff6ce24f78bffffdcfec16 --- /dev/null +++ b/ProcessLib/RichardsFlow/CreateRichardsFlowMaterialProperties.h @@ -0,0 +1,29 @@ +/** + * \copyright + * Copyright (c) 2012-2017, 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 "RichardsFlowMaterialProperties.h" +namespace BaseLib +{ +class ConfigTree; +} + +namespace ProcessLib +{ +namespace RichardsFlow +{ +std::unique_ptr<RichardsFlowMaterialProperties> +createRichardsFlowMaterialProperties( + BaseLib::ConfigTree const& config, + boost::optional<MeshLib::PropertyVector<int> const&> + material_ids); + +} // end namespace +} // end namespace diff --git a/ProcessLib/RichardsFlow/CreateRichardsFlowProcess.cpp b/ProcessLib/RichardsFlow/CreateRichardsFlowProcess.cpp index 5355698ef95b0ef27d211196af52f686dc000a20..bdcde323b286a701d5cb58b6b8bea000dddebe38 100644 --- a/ProcessLib/RichardsFlow/CreateRichardsFlowProcess.cpp +++ b/ProcessLib/RichardsFlow/CreateRichardsFlowProcess.cpp @@ -9,9 +9,11 @@ #include "CreateRichardsFlowProcess.h" +#include "ProcessLib/Parameter/ConstantParameter.h" #include "ProcessLib/Utils/ParseSecondaryVariables.h" #include "ProcessLib/Utils/ProcessUtils.h" -#include "ProcessLib/Parameter/ConstantParameter.h" + +#include "CreateRichardsFlowMaterialProperties.h" #include "RichardsFlowProcess.h" #include "RichardsFlowProcessData.h" @@ -45,75 +47,6 @@ std::unique_ptr<Process> createRichardsFlowProcess( {//! \ogs_file_param_special{prj__processes__process__RICHARDS_FLOW__process_variables__process_variable} "process_variable"}); - // Hydraulic conductivity parameter. - auto& intrinsic_permeability = findParameter<double>( - config, - //! \ogs_file_param_special{prj__processes__process__RICHARDS_FLOW__intrinsic_permeability} - "intrinsic_permeability", parameters, 1); - - DBUG("Use \'%s\' as intrinsic permeability parameter.", - intrinsic_permeability.name.c_str()); - - // Porosity parameter. - auto& porosity = findParameter<double>( - config, - //! \ogs_file_param_special{prj__processes__process__RICHARDS_FLOW__porosity} - "porosity", parameters, 1); - - DBUG("Use \'%s\' as porosity parameter.", porosity.name.c_str()); - - // Viscosity parameter. - auto& viscosity = findParameter<double>( - config, - //! \ogs_file_param_special{prj__processes__process__RICHARDS_FLOW__viscosity} - "viscosity", parameters, 1); - - DBUG("Use \'%s\' as porosity parameter.", viscosity.name.c_str()); - - // storage parameter. - auto& storage = findParameter<double>( - config, - //! \ogs_file_param_special{prj__processes__process__RICHARDS_FLOW__storage} - "storage", parameters, 1); - - DBUG("Use \'%s\' as storage parameter.", storage.name.c_str()); - - // water_density parameter. - auto& water_density = findParameter<double>( - config, - //! \ogs_file_param_special{prj__processes__process__RICHARDS_FLOW__water_density} - "water_density", parameters, 1); - - DBUG("Use \'%s\' as storage parameter.", water_density.name.c_str()); - - // Specific body force parameter. - auto& specific_body_force = findParameter<double>( - config, - //! \ogs_file_param_special{prj__processes__process__RICHARDS_FLOW__specific_body_force} - "specific_body_force", parameters, mesh.getDimension()); - DBUG("Use \'%s\' as specific body force parameter.", - specific_body_force.name.c_str()); - - // Assume constant parameter, then check the norm at arbitrary - // SpatialPosition and time. - assert(dynamic_cast<ConstantParameter<double>*>(&specific_body_force)); - bool const has_gravity = - MathLib::toVector(specific_body_force(0, SpatialPosition{})).norm() > 0; - - // has mass lumping - //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__mass_lumping} - auto mass_lump = config.getConfigParameter<bool>("mass_lumping"); - - RichardsFlowProcessData process_data{intrinsic_permeability, - porosity, - viscosity, - storage, - water_density, - specific_body_force, - has_gravity, - mass_lump, - *curves.at("curve_PC_S"), - *curves.at("curve_S_Krel")}; SecondaryVariableCollection secondary_variables; NumLib::NamedFunctionCaller named_function_caller( @@ -122,10 +55,50 @@ std::unique_ptr<Process> createRichardsFlowProcess( ProcessLib::parseSecondaryVariables(config, secondary_variables, named_function_caller); + // Specific body force + std::vector<double> const b = + //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__specific_body_force} + config.getConfigParameter<std::vector<double>>("specific_body_force"); + assert(b.size() > 0 && b.size() < 4); + Eigen::VectorXd specific_body_force(b.size()); + bool const has_gravity = MathLib::toVector(b).norm() > 0; + if (has_gravity) + std::copy_n(b.data(), b.size(), specific_body_force.data()); + + // has mass lumping + //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__mass_lumping} + auto mass_lumping = config.getConfigParameter<bool>("mass_lumping"); + + auto& temperature = findParameter<double>( + config, + //! \ogs_file_param_special{prj__processes__process__RICHARDS_FLOW__temperature} + "temperature", parameters, 1); + + //! \ogs_file_param{prj__processes__process__RICHARDS_FLOW__material_property} + auto const& mat_config = config.getConfigSubtree("material_property"); + + boost::optional<MeshLib::PropertyVector<int> const&> material_ids; + if (mesh.getProperties().existsPropertyVector<int>("MaterialIDs")) + { + INFO("The Richards flow is in heterogeneous porous media."); + material_ids = + *mesh.getProperties().getPropertyVector<int>("MaterialIDs"); + } + else + { + INFO("The Richards flow is in homogeneous porous media."); + } + std::unique_ptr<RichardsFlowMaterialProperties> material = + createRichardsFlowMaterialProperties(mat_config, material_ids); + RichardsFlowProcessData process_data{std::move(material), + specific_body_force, has_gravity, + mass_lumping, temperature}; + return std::make_unique<RichardsFlowProcess>( mesh, std::move(jacobian_assembler), parameters, integration_order, std::move(process_variables), std::move(process_data), - std::move(secondary_variables), std::move(named_function_caller)); + std::move(secondary_variables), std::move(named_function_caller), + mat_config, curves); } } // namespace RichardsFlow diff --git a/ProcessLib/RichardsFlow/RichardsFlowFEM.h b/ProcessLib/RichardsFlow/RichardsFlowFEM.h index caf5a78f60533223ae539f9068584dd42d8a4c7a..319bbacd977d968385ed72d5bb0d855934450262 100644 --- a/ProcessLib/RichardsFlow/RichardsFlowFEM.h +++ b/ProcessLib/RichardsFlow/RichardsFlowFEM.h @@ -28,6 +28,26 @@ namespace ProcessLib { namespace RichardsFlow { +template <typename NodalRowVectorType, typename GlobalDimNodalMatrixType, + typename NodalMatrixType> +struct IntegrationPointData final +{ + IntegrationPointData(NodalRowVectorType const& N_, + GlobalDimNodalMatrixType const& dNdx_, + double const& integration_weight_, + NodalMatrixType const mass_operator_) + : N(N_), + dNdx(dNdx_), + integration_weight(integration_weight_), + mass_operator(mass_operator_) + { + } + + NodalRowVectorType const N; + GlobalDimNodalMatrixType const dNdx; + double const integration_weight; + NodalMatrixType const mass_operator; +}; const unsigned NUM_NODAL_DOF = 1; class RichardsFlowLocalAssemblerInterface @@ -58,28 +78,54 @@ class LocalAssemblerData : public RichardsFlowLocalAssemblerInterface using LocalAssemblerTraits = ProcessLib::LocalAssemblerTraits< ShapeMatricesType, ShapeFunction::NPOINTS, NUM_NODAL_DOF, GlobalDim>; - using NodalMatrixType = typename LocalAssemblerTraits::LocalMatrix; - using NodalVectorType = typename LocalAssemblerTraits::LocalVector; + using NodalRowVectorType = typename ShapeMatricesType::NodalRowVectorType; + using GlobalDimNodalMatrixType = + typename ShapeMatricesType::GlobalDimNodalMatrixType; + using NodalMatrixType = typename ShapeMatricesType::NodalMatrixType; + using NodalVectorType = typename ShapeMatricesType::NodalVectorType; + using GlobalDimMatrixType = typename ShapeMatricesType::GlobalDimMatrixType; using GlobalDimVectorType = typename ShapeMatricesType::GlobalDimVectorType; public: LocalAssemblerData(MeshLib::Element const& element, - std::size_t const /*local_matrix_size*/, + std::size_t const local_matrix_size, bool is_axially_symmetric, unsigned const integration_order, RichardsFlowProcessData const& process_data) : _element(element), _process_data(process_data), _integration_method(integration_order), - _shape_matrices(initShapeMatrices<ShapeFunction, ShapeMatricesType, - IntegrationMethod, GlobalDim>( - element, is_axially_symmetric, _integration_method)), _saturation( std::vector<double>(_integration_method.getNumberOfPoints())), _darcy_velocities( GlobalDim, std::vector<double>(_integration_method.getNumberOfPoints())) { + // This assertion is valid only if all nodal d.o.f. use the same shape + // matrices. + assert(local_matrix_size == ShapeFunction::NPOINTS * NUM_NODAL_DOF); + (void)local_matrix_size; + + unsigned const n_integration_points = + _integration_method.getNumberOfPoints(); + _ip_data.reserve(n_integration_points); + + auto const shape_matrices = + initShapeMatrices<ShapeFunction, ShapeMatricesType, + IntegrationMethod, GlobalDim>( + element, is_axially_symmetric, _integration_method); + + for (unsigned ip = 0; ip < n_integration_points; ip++) + { + auto const& sm = shape_matrices[ip]; + const double integration_factor = sm.integralMeasure * sm.detJ; + _ip_data.emplace_back( + sm.N, sm.dNdx, + _integration_method.getWeightedPoint(ip).getWeight() * + integration_factor, + sm.N.transpose() * sm.N * integration_factor * + _integration_method.getWeightedPoint(ip).getWeight()); + } } void assemble(double const t, std::vector<double> const& local_x, @@ -92,11 +138,6 @@ public: // matrices. assert(local_matrix_size == ShapeFunction::NPOINTS * NUM_NODAL_DOF); - MathLib::PiecewiseLinearInterpolation const& interpolated_Pc = - _process_data.interpolated_Pc; - MathLib::PiecewiseLinearInterpolation const& interpolated_Kr = - _process_data.interpolated_Kr; - auto local_M = MathLib::createZeroedMatrix<NodalMatrixType>( local_M_data, local_matrix_size, local_matrix_size); auto local_K = MathLib::createZeroedMatrix<NodalMatrixType>( @@ -108,59 +149,72 @@ public: _integration_method.getNumberOfPoints(); SpatialPosition pos; pos.setElementID(_element.getID()); + const int material_id = + _process_data.material->getMaterialID(_element.getID()); + const Eigen::MatrixXd& perm = _process_data.material->getPermeability( + material_id, t, pos, _element.getDimension()); + assert(perm.rows() == _element.getDimension() || perm.rows() == 1); + GlobalDimMatrixType permeability = GlobalDimMatrixType::Zero( + _element.getDimension(), _element.getDimension()); + if (perm.rows() == _element.getDimension()) + permeability = perm; + else if (perm.rows() == 1) + permeability.diagonal().setConstant(perm(0, 0)); for (unsigned ip = 0; ip < n_integration_points; ip++) { pos.setIntegrationPoint(ip); - auto const& sm = _shape_matrices[ip]; - auto const& wp = _integration_method.getWeightedPoint(ip); - - double P_int_pt = 0.0; - NumLib::shapeFunctionInterpolate(local_x, sm.N, P_int_pt); - - auto const K = _process_data.intrinsic_permeability(t, pos)[0]; - auto const poro = _process_data.porosity(t, pos)[0]; - auto const mu = _process_data.viscosity(t, pos)[0]; - auto const storage = _process_data.storage(t, pos)[0]; - double const Pc = -P_int_pt; - - double dSwdPc = interpolated_Pc.getDerivative(Pc); - if (Pc > interpolated_Pc.getSupportMax()) - dSwdPc = interpolated_Pc.getDerivative( - interpolated_Pc.getSupportMax()); - else if (Pc < interpolated_Pc.getSupportMin()) - dSwdPc = interpolated_Pc.getDerivative( - interpolated_Pc.getSupportMin()); - - double const Sw = interpolated_Pc.getValue(Pc); + double p_int_pt = 0.0; + NumLib::shapeFunctionInterpolate(local_x, _ip_data[ip].N, p_int_pt); + const double& temperature = _process_data.temperature(t, pos)[0]; + auto const porosity = _process_data.material->getPorosity( + material_id, t, pos, p_int_pt, temperature, 0); + + double const pc_int_pt = -p_int_pt; + + double const Sw = + (pc_int_pt > 0) + ? _process_data.material->getSaturation( + material_id, t, pos, p_int_pt, temperature, pc_int_pt) + : 1.0; _saturation[ip] = Sw; - double const k_rel = interpolated_Kr.getValue(Sw); + double const dSw_dpc = + (pc_int_pt > 0) + ? _process_data.material->getSaturationDerivative( + material_id, t, pos, p_int_pt, temperature, Sw) + : 0.; + // \TODO Extend to pressure dependent density. double const drhow_dp(0.0); - + auto const storage = _process_data.material->getStorage( + material_id, t, pos, p_int_pt, temperature, 0); double const mass_mat_coeff = - storage * Sw + poro * Sw * drhow_dp - poro * dSwdPc; - double const K_mat_coeff = K * k_rel / mu; + storage * Sw + porosity * Sw * drhow_dp - porosity * dSw_dpc; - local_K.noalias() += sm.dNdx.transpose() * K_mat_coeff * sm.dNdx * - sm.detJ * sm.integralMeasure * wp.getWeight(); + local_M.noalias() += mass_mat_coeff * _ip_data[ip].mass_operator; + + double const k_rel = + _process_data.material->getRelativePermeability( + t, pos, p_int_pt, temperature, Sw); + auto const mu = _process_data.material->getFluidViscosity( + p_int_pt, temperature); + local_K.noalias() += _ip_data[ip].dNdx.transpose() * permeability * + _ip_data[ip].dNdx * + _ip_data[ip].integration_weight * (k_rel / mu); - local_M.noalias() += sm.N.transpose() * mass_mat_coeff * sm.N * - sm.detJ * sm.integralMeasure * wp.getWeight(); if (_process_data.has_gravity) { - auto const rho_w = _process_data.water_density(t, pos)[0]; - auto const body_force = - _process_data.specific_body_force(t, pos); + auto const rho_w = _process_data.material->getFluidDensity( + p_int_pt, temperature); + auto const& body_force = _process_data.specific_body_force; assert(body_force.size() == GlobalDim); - auto const b = MathLib::toVector<GlobalDimVectorType>( - body_force, GlobalDim); - local_b.noalias() += sm.dNdx.transpose() * K_mat_coeff * rho_w * - b * sm.detJ * sm.integralMeasure * - wp.getWeight(); + NodalVectorType gravity_operator = + _ip_data[ip].dNdx.transpose() * permeability * body_force * + _ip_data[ip].integration_weight; + local_b.noalias() += (k_rel / mu) * rho_w * gravity_operator; } - } // end of GP + } if (_process_data.has_mass_lumping) { for (int idx_ml = 0; idx_ml < local_M.cols(); idx_ml++) @@ -177,13 +231,18 @@ public: { SpatialPosition pos; pos.setElementID(_element.getID()); - - auto const K = _process_data.intrinsic_permeability(t, pos)[0]; - MathLib::PiecewiseLinearInterpolation const& interpolated_Pc = - _process_data.interpolated_Pc; - MathLib::PiecewiseLinearInterpolation const& interpolated_Kr = - _process_data.interpolated_Kr; - auto const mu = _process_data.viscosity(t, pos)[0]; + const int material_id = + _process_data.material->getMaterialID(_element.getID()); + + const Eigen::MatrixXd& perm = _process_data.material->getPermeability( + material_id, t, pos, _element.getDimension()); + assert(perm.rows() == _element.getDimension() || perm.rows() == 1); + GlobalDimMatrixType permeability = GlobalDimMatrixType::Zero( + _element.getDimension(), _element.getDimension()); + if (perm.rows() == _element.getDimension()) + permeability = perm; + else if (perm.rows() == 1) + permeability.diagonal().setConstant(perm(0, 0)); unsigned const n_integration_points = _integration_method.getNumberOfPoints(); @@ -193,27 +252,29 @@ public: for (unsigned ip = 0; ip < n_integration_points; ++ip) { - auto const& sm = _shape_matrices[ip]; - - double P_int_pt = 0.0; - NumLib::shapeFunctionInterpolate(local_x, sm.N, P_int_pt); - double const Pc = -P_int_pt; - double const Sw = interpolated_Pc.getValue(Pc); - double const k_rel = interpolated_Kr.getValue(Sw); - double const K_mat_coeff = K * k_rel / mu; - + double p_int_pt = 0.0; + NumLib::shapeFunctionInterpolate(local_x, _ip_data[ip].N, p_int_pt); + double const pc_int_pt = -p_int_pt; + const double& temperature = _process_data.temperature(t, pos)[0]; + double const Sw = _process_data.material->getSaturation( + material_id, t, pos, p_int_pt, temperature, pc_int_pt); + double const k_rel = + _process_data.material->getRelativePermeability( + t, pos, p_int_pt, temperature, Sw); + auto const mu = _process_data.material->getFluidViscosity( + p_int_pt, temperature); + auto const K_mat_coeff = permeability * (k_rel / mu); GlobalDimVectorType velocity = - -K_mat_coeff * sm.dNdx * p_nodal_values; + -K_mat_coeff * _ip_data[ip].dNdx * p_nodal_values; if (_process_data.has_gravity) { - auto const rho_w = _process_data.water_density(t, pos)[0]; - auto const body_force = - _process_data.specific_body_force(t, pos); + auto const rho_w = _process_data.material->getFluidDensity( + p_int_pt, temperature); + auto const& body_force = _process_data.specific_body_force; assert(body_force.size() == GlobalDim); - auto const b = MathLib::toVector<GlobalDimVectorType>( - body_force, GlobalDim); - // here it is assumed that the vector b is directed 'downwards' - velocity += K_mat_coeff * rho_w * b; + // here it is assumed that the vector body_force is directed + // 'downwards' + velocity += K_mat_coeff * rho_w * body_force; } for (unsigned d = 0; d < GlobalDim; ++d) @@ -226,7 +287,7 @@ public: Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix( const unsigned integration_point) const override { - auto const& N = _shape_matrices[integration_point].N; + auto const& N = _ip_data[integration_point].N; // assumes N is stored contiguously in memory return Eigen::Map<const Eigen::RowVectorXd>(N.data(), N.size()); @@ -267,7 +328,12 @@ private: IntegrationMethod const _integration_method; std::vector<ShapeMatrices, Eigen::aligned_allocator<ShapeMatrices>> _shape_matrices; - + std::vector< + IntegrationPointData<NodalRowVectorType, GlobalDimNodalMatrixType, + NodalMatrixType>, + Eigen::aligned_allocator<IntegrationPointData< + NodalRowVectorType, GlobalDimNodalMatrixType, NodalMatrixType>>> + _ip_data; std::vector<double> _saturation; std::vector<std::vector<double>> _darcy_velocities; }; diff --git a/ProcessLib/RichardsFlow/RichardsFlowMaterialProperties.cpp b/ProcessLib/RichardsFlow/RichardsFlowMaterialProperties.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3c5f64280b7077a777ff0e79ce5d5f4f8fb7d809 --- /dev/null +++ b/ProcessLib/RichardsFlow/RichardsFlowMaterialProperties.cpp @@ -0,0 +1,136 @@ +/** +* \copyright +* Copyright (c) 2012-2017, 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 "RichardsFlowMaterialProperties.h" + +#include <logog/include/logog.hpp> + +#include "BaseLib/reorderVector.h" +#include "MaterialLib/Fluid/FluidProperty.h" +#include "MaterialLib/PorousMedium/Porosity/Porosity.h" +#include "MaterialLib/PorousMedium/Storage/Storage.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/CapillaryPressure/CapillaryPressureSaturation.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/CapillaryPressure/CreateCapillaryPressureModel.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/RelativePermeability/CreateRelativePermeabilityModel.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/RelativePermeability/RelativePermeability.h" +#include "MeshLib/Mesh.h" +#include "MeshLib/PropertyVector.h" +#include "ProcessLib/Parameter/Parameter.h" +#include "ProcessLib/Parameter/SpatialPosition.h" + +namespace ProcessLib +{ +namespace RichardsFlow +{ +RichardsFlowMaterialProperties::RichardsFlowMaterialProperties( + boost::optional<MeshLib::PropertyVector<int> const&> const material_ids, + std::unique_ptr<MaterialLib::Fluid::FluidProperties>&& fluid_properties, + std::vector<Eigen::MatrixXd>&& intrinsic_permeability_models, + std::vector<std::unique_ptr<MaterialLib::PorousMedium::Porosity>>&& + porosity_models, + std::vector<std::unique_ptr<MaterialLib::PorousMedium::Storage>>&& + storage_models, + std::vector<std::unique_ptr< + MaterialLib::PorousMedium::CapillaryPressureSaturation>>&& + capillary_pressure_models, + std::vector< + std::unique_ptr<MaterialLib::PorousMedium::RelativePermeability>>&& + relative_permeability_models) + : _material_ids(material_ids), + _fluid_properties(std::move(fluid_properties)), + _intrinsic_permeability_models(intrinsic_permeability_models), + _porosity_models(std::move(porosity_models)), + _storage_models(std::move(storage_models)), + _capillary_pressure_models(std::move(capillary_pressure_models)), + _relative_permeability_models(std::move(relative_permeability_models)) +{ + DBUG("Create material properties for Richards flow."); +} + +int RichardsFlowMaterialProperties::getMaterialID(const std::size_t element_id) +{ + if (!_material_ids) + { + return 0; + } + + assert(element_id < _material_ids->size()); + return (*_material_ids)[element_id]; +} + +double RichardsFlowMaterialProperties::getFluidDensity(const double p, + const double T) const +{ + ArrayType vars; + vars[static_cast<int>(MaterialLib::Fluid::PropertyVariableType::T)] = T; + vars[static_cast<int>(MaterialLib::Fluid::PropertyVariableType::p)] = p; + return _fluid_properties->getValue( + MaterialLib::Fluid::FluidPropertyType::Density, vars); +} + +double RichardsFlowMaterialProperties::getFluidViscosity(const double p, + const double T) const +{ + ArrayType vars; + vars[static_cast<int>(MaterialLib::Fluid::PropertyVariableType::T)] = T; + vars[static_cast<int>(MaterialLib::Fluid::PropertyVariableType::p)] = p; + return _fluid_properties->getValue( + MaterialLib::Fluid::FluidPropertyType::Viscosity, vars); +} + +Eigen::MatrixXd const& RichardsFlowMaterialProperties::getPermeability( + const int material_id, const double /*t*/, + const ProcessLib::SpatialPosition& /*pos*/, const int /*dim*/) const +{ + return _intrinsic_permeability_models[material_id]; +} + +double RichardsFlowMaterialProperties::getPorosity( + const int material_id, const double /*t*/, + const ProcessLib::SpatialPosition& /*pos*/, const double /*p*/, + const double T, const double porosity_variable) const +{ + return _porosity_models[material_id]->getValue(porosity_variable, T); +} + +double RichardsFlowMaterialProperties::getStorage( + const int material_id, const double /*t*/, + const ProcessLib::SpatialPosition& /*pos*/, const double /*p*/, + const double /*T*/, const double storage_variable) const +{ + // \todo getValue() can be extended for non + // constant storage model + return _storage_models[material_id]->getValue(storage_variable); +} + +double RichardsFlowMaterialProperties::getRelativePermeability( + const double /*t*/, const ProcessLib::SpatialPosition& /*pos*/, + const double /*p*/, const double /*T*/, const double saturation) const +{ + return _relative_permeability_models[0]->getValue(saturation); +} + +double RichardsFlowMaterialProperties::getSaturation( + const int material_id, const double /*t*/, + const ProcessLib::SpatialPosition& /*pos*/, const double /*p*/, + const double /*T*/, const double pc) const +{ + return _capillary_pressure_models[material_id]->getSaturation(pc); +} +double RichardsFlowMaterialProperties::getSaturationDerivative( + const int material_id, const double /*t*/, + const ProcessLib::SpatialPosition& /*pos*/, const double /*p*/, + const double /*T*/, const double saturation) const +{ + const double dpcdsw = + _capillary_pressure_models[material_id]->getdPcdS(saturation); + return 1 / dpcdsw; +} +} // end of namespace +} // end of namespace diff --git a/ProcessLib/RichardsFlow/RichardsFlowMaterialProperties.h b/ProcessLib/RichardsFlow/RichardsFlowMaterialProperties.h new file mode 100644 index 0000000000000000000000000000000000000000..cf6db124c526c25b9dc8a6d93c1a9092afaaa1ca --- /dev/null +++ b/ProcessLib/RichardsFlow/RichardsFlowMaterialProperties.h @@ -0,0 +1,121 @@ +/** +* \copyright +* Copyright (c) 2012-2017, 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> +#include <vector> + +#include "MaterialLib/Fluid/FluidPropertyHeaders.h" +#include "MaterialLib/Fluid/FluidProperties/FluidProperties.h" +#include "MaterialLib/PhysicalConstant.h" +#include "MaterialLib/PorousMedium/Porosity/Porosity.h" +#include "MaterialLib/PorousMedium/PorousPropertyHeaders.h" +#include "MaterialLib/PorousMedium/Storage/Storage.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/CapillaryPressure/CapillaryPressureSaturation.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/CapillaryPressure/CreateCapillaryPressureModel.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/RelativePermeability/CreateRelativePermeabilityModel.h" +#include "MaterialLib/PorousMedium/UnsaturatedProperty/RelativePermeability/RelativePermeability.h" + +namespace MeshLib +{ +template <typename PROP_VAL_TYPE> +class PropertyVector; +} + +namespace ProcessLib +{ +class SpatialPosition; +namespace RichardsFlow +{ +/** This class has a collection of material properties for Richards flow model +* and it makes description of the properties of unsaturated porous media +* i.e. the fluid density and viscosity models +* the relative permeability models, +* the capillary pressure-saturation relationships. +* It generally provides the computation of the PDE coefficients for Richards +* flow. +*/ + +class RichardsFlowMaterialProperties final +{ +public: + using ArrayType = MaterialLib::Fluid::FluidProperty::ArrayType; + + RichardsFlowMaterialProperties( + boost::optional<MeshLib::PropertyVector<int> const&> const material_ids, + std::unique_ptr<MaterialLib::Fluid::FluidProperties>&& fluid_properties, + std::vector<Eigen::MatrixXd>&& intrinsic_permeability_models, + std::vector<std::unique_ptr<MaterialLib::PorousMedium::Porosity>>&& + porosity_models, + std::vector<std::unique_ptr<MaterialLib::PorousMedium::Storage>>&& + storage_models, + std::vector<std::unique_ptr< + MaterialLib::PorousMedium::CapillaryPressureSaturation>>&& + capillary_pressure_models, + std::vector< + std::unique_ptr<MaterialLib::PorousMedium::RelativePermeability>>&& + relative_permeability_models); + + int getMaterialID(const std::size_t element_id); + + Eigen::MatrixXd const& getPermeability( + const int material_id, + const double t, + const ProcessLib::SpatialPosition& pos, + const int dim) const; + + double getPorosity(const int material_id, const double t, + const ProcessLib::SpatialPosition& pos, const double p, + const double T, const double porosity_variable) const; + + double getStorage( + const int material_id, const double t, + const ProcessLib::SpatialPosition& pos, const double p, + const double T, const double storage_variable) const; + + double getRelativePermeability(const double t, + const ProcessLib::SpatialPosition& pos, + const double p, const double T, + const double saturation) const; + + double getSaturation(const int material_id, const double t, + const ProcessLib::SpatialPosition& pos, const double p, + const double T, const double pc) const; + double getSaturationDerivative(const int material_id, const double t, + const ProcessLib::SpatialPosition& pos, + const double p, const double T, + const double saturation) const; + double getFluidDensity(const double p, const double T) const; + double getFluidViscosity(const double p, const double T) const; + +private: + /** + * Material IDs must be given as mesh element properties. + */ + boost::optional<MeshLib::PropertyVector<int> const&> const _material_ids; + + const std::unique_ptr<MaterialLib::Fluid::FluidProperties> + _fluid_properties; + + std::vector<Eigen::MatrixXd> const _intrinsic_permeability_models; + std::vector<std::unique_ptr<MaterialLib::PorousMedium::Porosity>> const + _porosity_models; + std::vector<std::unique_ptr<MaterialLib::PorousMedium::Storage>> const + _storage_models; + std::vector<std::unique_ptr< + MaterialLib::PorousMedium::CapillaryPressureSaturation>> const + _capillary_pressure_models; + std::vector< + std::unique_ptr<MaterialLib::PorousMedium::RelativePermeability>> const + _relative_permeability_models; +}; + +} // end of namespace +} // end of namespace diff --git a/ProcessLib/RichardsFlow/RichardsFlowProcess.cpp b/ProcessLib/RichardsFlow/RichardsFlowProcess.cpp index 2b3d2a741792628ca8a926fc3fbeac4ad816efcc..c87d3dd6cdf843931c0a104d42f4ce22b5e3b5e8 100644 --- a/ProcessLib/RichardsFlow/RichardsFlowProcess.cpp +++ b/ProcessLib/RichardsFlow/RichardsFlowProcess.cpp @@ -25,7 +25,11 @@ RichardsFlowProcess::RichardsFlowProcess( std::vector<std::reference_wrapper<ProcessVariable>>&& process_variables, RichardsFlowProcessData&& process_data, SecondaryVariableCollection&& secondary_variables, - NumLib::NamedFunctionCaller&& named_function_caller) + NumLib::NamedFunctionCaller&& named_function_caller, + BaseLib::ConfigTree const& /*config*/, + std::map<std::string, + std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const& + /*curves*/) : Process(mesh, std::move(jacobian_assembler), parameters, integration_order, std::move(process_variables), std::move(secondary_variables), std::move(named_function_caller)), @@ -74,13 +78,13 @@ void RichardsFlowProcess::initializeConcreteProcess( } } -void RichardsFlowProcess::assembleConcreteProcess(const double t, - GlobalVector const& x, - GlobalMatrix& M, - GlobalMatrix& K, - GlobalVector& b, - StaggeredCouplingTerm const& - coupling_term) +void RichardsFlowProcess::assembleConcreteProcess( + const double t, + GlobalVector const& x, + GlobalMatrix& M, + GlobalMatrix& K, + GlobalVector& b, + StaggeredCouplingTerm const& coupling_term) { DBUG("Assemble RichardsFlowProcess."); diff --git a/ProcessLib/RichardsFlow/RichardsFlowProcess.h b/ProcessLib/RichardsFlow/RichardsFlowProcess.h index 6832699082d830df9fde213a7be616a3689654a1..f1b44fa2272d61ddcdb5e666c538dc29e4349cba 100644 --- a/ProcessLib/RichardsFlow/RichardsFlowProcess.h +++ b/ProcessLib/RichardsFlow/RichardsFlowProcess.h @@ -11,6 +11,7 @@ #include "NumLib/Extrapolation/LocalLinearLeastSquaresExtrapolator.h" #include "ProcessLib/Process.h" + #include "RichardsFlowFEM.h" #include "RichardsFlowProcessData.h" @@ -33,7 +34,11 @@ public: process_variables, RichardsFlowProcessData&& process_data, SecondaryVariableCollection&& secondary_variables, - NumLib::NamedFunctionCaller&& named_function_caller); + NumLib::NamedFunctionCaller&& named_function_caller, + BaseLib::ConfigTree const& config, + std::map<std::string, + std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const& + curves); //! \name ODESystem interface //! @{ @@ -51,11 +56,9 @@ private: MeshLib::Mesh const& mesh, unsigned const integration_order) override; - void assembleConcreteProcess(const double t, GlobalVector const& x, - GlobalMatrix& M, GlobalMatrix& K, - GlobalVector& b, - StaggeredCouplingTerm const& coupling_term - ) override; + void assembleConcreteProcess( + const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K, + GlobalVector& b, StaggeredCouplingTerm const& coupling_term) override; void assembleWithJacobianConcreteProcess( const double t, GlobalVector const& x, GlobalVector const& xdot, diff --git a/ProcessLib/RichardsFlow/RichardsFlowProcessData.h b/ProcessLib/RichardsFlow/RichardsFlowProcessData.h index 4d7ea9ebb51750fc428e8dd9bacd576b557c3f1d..a2c0a9419c54e0392ed9bad6553c3bdc47b8db5e 100644 --- a/ProcessLib/RichardsFlow/RichardsFlowProcessData.h +++ b/ProcessLib/RichardsFlow/RichardsFlowProcessData.h @@ -8,11 +8,7 @@ */ #pragma once - -namespace MeshLib -{ -class Element; -} +#include "RichardsFlowMaterialProperties.h" namespace ProcessLib { @@ -24,40 +20,25 @@ namespace RichardsFlow struct RichardsFlowProcessData { RichardsFlowProcessData( - Parameter<double> const& intrinsic_permeability_, - Parameter<double> const& porosity_, - Parameter<double> const& viscosity_, - Parameter<double> const& storage_, - Parameter<double> const& water_density_, - Parameter<double> const& specific_body_force_, + std::unique_ptr<RichardsFlowMaterialProperties>&& material_, + Eigen::VectorXd const specific_body_force_, bool const has_gravity_, bool const has_mass_lumping_, - MathLib::PiecewiseLinearInterpolation const& interpolated_Pc_, - MathLib::PiecewiseLinearInterpolation const& interpolated_Kr_) - : intrinsic_permeability(intrinsic_permeability_), - porosity(porosity_), - viscosity(viscosity_), - storage(storage_), - water_density(water_density_), + Parameter<double> const& temperature_) + : material(std::move(material_)), specific_body_force(specific_body_force_), has_gravity(has_gravity_), has_mass_lumping(has_mass_lumping_), - interpolated_Pc(interpolated_Pc_), - interpolated_Kr(interpolated_Kr_) + temperature(temperature_) { } RichardsFlowProcessData(RichardsFlowProcessData&& other) - : intrinsic_permeability(other.intrinsic_permeability), - porosity(other.porosity), - viscosity(other.viscosity), - storage(other.storage), - water_density(other.water_density), + : material(std::move(other.material)), specific_body_force(other.specific_body_force), has_gravity(other.has_gravity), has_mass_lumping(other.has_mass_lumping), - interpolated_Pc(other.interpolated_Pc), - interpolated_Kr(other.interpolated_Kr) + temperature(other.temperature) { } @@ -70,16 +51,11 @@ struct RichardsFlowProcessData //! Assignments are not needed. void operator=(RichardsFlowProcessData&&) = delete; - Parameter<double> const& intrinsic_permeability; - Parameter<double> const& porosity; - Parameter<double> const& viscosity; - Parameter<double> const& storage; - Parameter<double> const& water_density; - Parameter<double> const& specific_body_force; + std::unique_ptr<RichardsFlowMaterialProperties> material; + Eigen::VectorXd const specific_body_force; bool const has_gravity; bool const has_mass_lumping; - MathLib::PiecewiseLinearInterpolation const& interpolated_Pc; - MathLib::PiecewiseLinearInterpolation const& interpolated_Kr; + Parameter<double> const& temperature; }; } // namespace RichardsFlow diff --git a/ProcessLib/RichardsFlow/Tests.cmake b/ProcessLib/RichardsFlow/Tests.cmake index 46511bb561d41e3afbb08c151ea7fdc2eecc1008..35b569a8d578bc4b292ee4d98cadba46c1c6acb0 100644 --- a/ProcessLib/RichardsFlow/Tests.cmake +++ b/ProcessLib/RichardsFlow/Tests.cmake @@ -1,11 +1,33 @@ AddTest( - NAME LARGE_2D_RichardsFlow_h_us_quad + NAME 2D_RichardsFlow_h_us_quad_ogs5 PATH Parabolic/Richards EXECUTABLE ogs - EXECUTABLE_ARGS RichardsFlow_2d.prj + EXECUTABLE_ARGS RichardsFlow_2d_compare_ogs5.prj TESTER vtkdiff ABSTOL 1e-1 RELTOL 1e-1 DIFF_DATA h_us_quad_1000.vtu richards_pcs_0_ts_100_t_100.000000.vtu PRESSURE1 pressure REQUIREMENTS NOT OGS_USE_MPI ) +AddTest( + NAME 2D_RichardsFlow_h_us_quad_small + PATH Parabolic/Richards + EXECUTABLE ogs + EXECUTABLE_ARGS RichardsFlow_2d_small.prj + TESTER vtkdiff + ABSTOL 1e-8 RELTOL 1e-8 + DIFF_DATA + ref_t_1600.000000.vtu richards_pcs_0_ts_1100_t_1600.000000.vtu pressure pressure + REQUIREMENTS NOT OGS_USE_MPI +) +AddTest( + NAME LARGE_2D_RichardsFlow_h_us_quad + PATH Parabolic/Richards + EXECUTABLE ogs + EXECUTABLE_ARGS RichardsFlow_2d_large.prj + TESTER vtkdiff + ABSTOL 1e-8 RELTOL 1e-8 + DIFF_DATA + ref_t_20000.000000.vtu richards_pcs_0_ts_18200_t_20000.000000.vtu pressure pressure + REQUIREMENTS NOT OGS_USE_MPI +) diff --git a/Tests/Data b/Tests/Data index a456c5b48e931239647852196feef1ca6fb0dece..1b30c432bbe45271710b54e83f84ad4f5d75a033 160000 --- a/Tests/Data +++ b/Tests/Data @@ -1 +1 @@ -Subproject commit a456c5b48e931239647852196feef1ca6fb0dece +Subproject commit 1b30c432bbe45271710b54e83f84ad4f5d75a033