Revision 7f8d24a6d3d1e277300e118db7925769cae38e21 authored by Thomas Fischer on 06 April 2023, 08:02:11 UTC, committed by Thomas Fischer on 26 April 2023, 04:41:49 UTC
1 parent 748c483
ThermoporoelasticityMFront.cpp
/**
* \file
* \copyright
* Copyright (c) 2012-2023, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*/
#ifdef OGS_USE_MFRONT
#include <gtest/gtest.h>
#include "BaseLib/ConfigTree.h"
#include "MaterialLib/SolidModels/MFront/CreateMFrontGeneric.h"
#include "MaterialLib/SolidModels/MFront/Variable.h"
#include "ParameterLib/ConstantParameter.h"
#include "Tests/TestTools.h"
static void print_header()
{
std::cout << R"(# first column: time
# 2 column: 1th component of the gradients (StrainXX)
# 3 column: 2th component of the gradients (StrainYY)
# 4 column: 3th component of the gradients (StrainZZ)
# 5 column: 4th component of the gradients (StrainXY)
# 6 column: 5th component of the gradients (StrainXZ)
# 7 column: 6th component of the gradients (StrainYZ)
# 8 column: 7th component of the gradients (LiquidPressure)
# 9 column: 1th component of the thermodynamic forces (StressXX)
# 10 column: 2th component of the thermodynamic forces (StressYY)
# 11 column: 3th component of the thermodynamic forces (StressZZ)
# 12 column: 4th component of the thermodynamic forces (StressXY)
# 13 column: 5th component of the thermodynamic forces (StressXZ)
# 14 column: 6th component of the thermodynamic forces (StressYZ)
# 15 column: 7th component of the thermodynamic forces (Saturation)
# 16 column: stored energy
# 17 column: dissipated energy
)";
}
static void print(double const t,
MaterialPropertyLib::VariableArray const& vars)
{
namespace MPL = MaterialPropertyLib;
using KV = MathLib::KelvinVector::KelvinVectorType<3>;
auto const strain = MaterialLib::Solids::MFront::MFrontToOGS(
std::get<KV>(vars.mechanical_strain));
auto const p = vars.liquid_phase_pressure;
auto const stress =
MaterialLib::Solids::MFront::MFrontToOGS(std::get<KV>(vars.stress));
auto const S_L = vars.liquid_saturation;
std::cout << t //
<< ' ' << strain[0] << ' ' << strain[1] << ' ' << strain[2] << ' '
<< strain[3] << ' ' << strain[4] << ' ' << strain[5] //
<< ' ' << p //
<< ' ' << stress[0] << ' ' << stress[1] << ' ' << stress[2] << ' '
<< stress[3] << ' ' << stress[4] << ' ' << stress[5] //
<< ' ' << S_L //
<< " 0 0\n";
}
static auto createParams()
{
std::vector<std::unique_ptr<ParameterLib::ParameterBase>> parameters;
auto add_param = [¶meters](const char* name, double value)
{
parameters.push_back(
std::make_unique<ParameterLib::ConstantParameter<double>>(name,
value));
};
add_param("E", 10e9);
add_param("nu", 0.3);
add_param("alpha", 1e-5);
add_param("alpha_B", 1);
add_param("m_chi", 1);
add_param("S_L_res", 0);
add_param("S_G_res", 0);
add_param("p_b", 5e5);
add_param("m_S", 0.4);
return parameters;
}
static double sigma_xx_analytical(double const t)
{
double const E = 10e9;
double const nu = 0.3;
double const alphaTS = 1e-5;
double const dT = 40;
double const p_eff = 3 * E / (3 * (1 - 2 * nu)) * alphaTS * dT;
return -p_eff * t - 1e5;
}
static auto createMFront(
std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters)
{
auto local_coordinate_system = std::nullopt;
const char* xml = R"XML(
<type>MFront</type>
<behaviour>ThermoPoroElasticity</behaviour>
<material_properties>
<material_property name="YoungModulus" parameter="E"/>
<material_property name="PoissonRatio" parameter="nu"/>
<material_property name="ThermalExpansion" parameter="alpha"/>
<material_property name="BiotCoefficient" parameter="alpha_B"/>
<material_property name="BishopsExponent" parameter="m_chi"/>
<material_property name="ResidualLiquidSaturation" parameter="S_L_res"/>
<material_property name="ResidualGasSaturation" parameter="S_G_res"/>
<material_property name="BubblePressure" parameter="p_b"/>
<material_property name="VanGenuchtenExponent_m" parameter="m_S"/>
</material_properties>
)XML";
auto ptree = Tests::readXml(xml);
BaseLib::ConfigTree config_tree(std::move(ptree), "FILENAME",
&BaseLib::ConfigTree::onerror,
&BaseLib::ConfigTree::onwarning);
namespace MSM = MaterialLib::Solids::MFront;
return MSM::createMFrontGeneric<
3, boost::mp11::mp_list<MSM::Strain, MSM::LiquidPressure>,
boost::mp11::mp_list<MSM::Stress, MSM::Saturation>,
boost::mp11::mp_list<>>(parameters, local_coordinate_system,
config_tree, false);
}
TEST(MaterialLib_ThermoPoroElasticityMFront, IsochoricDrainedHeating)
{
namespace MSM = MaterialLib::Solids::MFront;
// Create MFront behaviour /////////////////////////////////////////////////
auto const parameters = createParams();
auto mfront_model = createMFront(parameters);
// Transient data //////////////////////////////////////////////////////////
const std::size_t num_ts = 11;
Eigen::VectorXd ts = Eigen::VectorXd::LinSpaced(num_ts, 0, 1);
Eigen::VectorXd Ts = Eigen::VectorXd::LinSpaced(num_ts, 293, 333);
// Set initial state ///////////////////////////////////////////////////////
auto state = mfront_model->createMaterialStateVariables();
namespace MPL = MaterialPropertyLib;
using KV = MathLib::KelvinVector::KelvinVectorType<3>;
MPL::VariableArray variable_array_prev;
// MFront thermodynamic forces
variable_array_prev.stress = KV{-1e5, -1e5, -1e5, 0, 0, 0};
variable_array_prev.liquid_saturation = 1.0;
// MFront gradients
variable_array_prev.mechanical_strain = KV::Zero().eval();
variable_array_prev.liquid_phase_pressure = 0.0;
// MFront external state
variable_array_prev.temperature = Ts[0];
// Integrate material behaviour ////////////////////////////////////////////
print_header();
print(ts[0], variable_array_prev);
for (std::size_t i = 1; i < num_ts; ++i)
{
MPL::VariableArray variable_array;
// MFront current state
variable_array.mechanical_strain = KV::Zero().eval();
variable_array.liquid_phase_pressure = 0.0;
variable_array.temperature = Ts[i];
// std::cout << "T = " << Ts[i] << '\n';
auto const t = ts[i];
auto const dt = t - ts[i - 1];
ParameterLib::SpatialPosition pos{};
// Integrate
auto solution = mfront_model->integrateStress(
variable_array_prev, variable_array, t, pos, dt, *state);
ASSERT_TRUE(solution);
// Save solution for next iteration
auto& [t_dyn_forces_data, new_state, stiffness_matrix] = *solution;
auto const view = mfront_model->createThermodynamicForcesView();
auto const stress = view.block(MSM::stress, t_dyn_forces_data);
auto const S_L = view.block(MSM::saturation, t_dyn_forces_data);
variable_array_prev = variable_array;
variable_array_prev.stress.emplace<KV>(stress);
variable_array_prev.liquid_saturation = S_L;
state = std::move(new_state);
print(t, variable_array_prev);
EXPECT_DOUBLE_EQ(sigma_xx_analytical(t), stress[0]);
}
}
#endif
Computing file changes ...