-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GeoMechanicsApplication] Implement well constitutive behaviour for line pressure element #12997
base: master
Are you sure you want to change the base?
Changes from all commits
399a931
f5e113b
6ff43bf
4d27652
5be7ec0
55c094e
0b630c8
af1d84d
e9ffca6
007bf56
f2d2ab7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// KRATOS___ | ||
// // ) ) | ||
// // ___ ___ | ||
// // ____ //___) ) // ) ) | ||
// // / / // // / / | ||
// ((____/ / ((____ ((___/ / MECHANICS | ||
// | ||
// License: geo_mechanics_application/license.txt | ||
// | ||
// Main authors: Mohamed Nabi | ||
// Richard Faasse | ||
// | ||
#include "filter_compressibility_calculator.h" | ||
#include "custom_utilities/transport_equation_utilities.hpp" | ||
#include "geo_mechanics_application_variables.h" | ||
|
||
namespace Kratos | ||
{ | ||
|
||
FilterCompressibilityCalculator::FilterCompressibilityCalculator(InputProvider AnInputProvider) | ||
: mInputProvider(std::move(AnInputProvider)) | ||
{ | ||
} | ||
|
||
Matrix FilterCompressibilityCalculator::LHSContribution() | ||
{ | ||
return LHSContribution(CalculateCompressibilityMatrix()); | ||
} | ||
|
||
Vector FilterCompressibilityCalculator::RHSContribution() | ||
{ | ||
return RHSContribution(CalculateCompressibilityMatrix()); | ||
} | ||
|
||
Vector FilterCompressibilityCalculator::RHSContribution(const Matrix& rCompressibilityMatrix) const | ||
{ | ||
return -prod(rCompressibilityMatrix, mInputProvider.GetNodalValues(DT_WATER_PRESSURE)); | ||
} | ||
|
||
Matrix FilterCompressibilityCalculator::LHSContribution(const Matrix& rCompressibilityMatrix) const | ||
{ | ||
return mInputProvider.GetMatrixScalarFactor() * rCompressibilityMatrix; | ||
} | ||
|
||
std::pair<Matrix, Vector> FilterCompressibilityCalculator::LocalSystemContribution() | ||
{ | ||
const auto compressibility_matrix = CalculateCompressibilityMatrix(); | ||
return {LHSContribution(compressibility_matrix), RHSContribution(compressibility_matrix)}; | ||
} | ||
|
||
Matrix FilterCompressibilityCalculator::CalculateCompressibilityMatrix() const | ||
{ | ||
const auto& r_N_container = mInputProvider.GetNContainer(); | ||
const auto& integration_coefficients = mInputProvider.GetIntegrationCoefficients(); | ||
const auto& projected_gravity_on_integration_points = | ||
mInputProvider.GetProjectedGravityForIntegrationPoints(); | ||
auto result = Matrix{ZeroMatrix{r_N_container.size2(), r_N_container.size2()}}; | ||
for (unsigned int integration_point_index = 0; | ||
integration_point_index < integration_coefficients.size(); ++integration_point_index) { | ||
const auto N = Vector{row(r_N_container, integration_point_index)}; | ||
result += GeoTransportEquationUtilities::CalculateCompressibilityMatrix( | ||
N, CalculateElasticCapacity(projected_gravity_on_integration_points[integration_point_index]), | ||
integration_coefficients[integration_point_index]); | ||
} | ||
return result; | ||
} | ||
|
||
double FilterCompressibilityCalculator::CalculateElasticCapacity(double ProjectedGravity) const | ||
{ | ||
const auto& r_properties = mInputProvider.GetElementProperties(); | ||
const double result = | ||
1.0 / (r_properties[DENSITY_WATER] * ProjectedGravity * r_properties[FILTER_LENGTH]) + | ||
1.0 / r_properties[BULK_MODULUS_FLUID]; | ||
return result; | ||
} | ||
|
||
const Properties& FilterCompressibilityCalculator::InputProvider::GetElementProperties() const | ||
{ | ||
return mGetElementProperties(); | ||
} | ||
|
||
const Matrix& FilterCompressibilityCalculator::InputProvider::GetNContainer() const | ||
{ | ||
return mGetNContainer(); | ||
} | ||
|
||
Vector FilterCompressibilityCalculator::InputProvider::GetIntegrationCoefficients() const | ||
{ | ||
return mGetIntegrationCoefficients(); | ||
} | ||
|
||
Vector FilterCompressibilityCalculator::InputProvider::GetProjectedGravityForIntegrationPoints() const | ||
{ | ||
return mGetProjectedGravityForIntegrationPoints(); | ||
} | ||
|
||
double FilterCompressibilityCalculator::InputProvider::GetMatrixScalarFactor() const | ||
{ | ||
return mGetMatrixScalarFactor(); | ||
} | ||
|
||
Vector FilterCompressibilityCalculator::InputProvider::GetNodalValues(const Variable<double>& rVariable) const | ||
{ | ||
return mGetNodalValues(rVariable); | ||
} | ||
|
||
} // namespace Kratos |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// KRATOS___ | ||
// // ) ) | ||
// // ___ ___ | ||
// // ____ //___) ) // ) ) | ||
// // / / // // / / | ||
// ((____/ / ((____ ((___/ / MECHANICS | ||
// | ||
// License: geo_mechanics_application/license.txt | ||
// | ||
// Main authors: Mohamed Nabi | ||
// Richard Faasse | ||
|
||
#pragma once | ||
|
||
#include "contribution_calculator.h" | ||
#include "custom_retention/retention_law.h" | ||
#include "includes/properties.h" | ||
#include "includes/ublas_interface.h" | ||
|
||
#include <utility> | ||
#include <vector> | ||
|
||
namespace Kratos | ||
{ | ||
|
||
class FilterCompressibilityCalculator : public ContributionCalculator | ||
{ | ||
public: | ||
class InputProvider | ||
{ | ||
public: | ||
InputProvider(std::function<const Properties&()> GetElementProperties, | ||
std::function<const Matrix&()> GetNContainer, | ||
std::function<Vector()> GetIntegrationCoefficients, | ||
std::function<Vector()> GetProjectedGravityForIntegrationPoints, | ||
std::function<double()> GetMatrixScalarFactor, | ||
std::function<Vector(const Variable<double>&)> GetNodalValuesOf) | ||
: mGetElementProperties(std::move(GetElementProperties)), | ||
mGetNContainer(std::move(GetNContainer)), | ||
mGetIntegrationCoefficients(std::move(GetIntegrationCoefficients)), | ||
mGetProjectedGravityForIntegrationPoints(std::move(GetProjectedGravityForIntegrationPoints)), | ||
mGetMatrixScalarFactor(std::move(GetMatrixScalarFactor)), | ||
mGetNodalValues(std::move(GetNodalValuesOf)) | ||
{ | ||
} | ||
|
||
[[nodiscard]] const Properties& GetElementProperties() const; | ||
[[nodiscard]] const Matrix& GetNContainer() const; | ||
[[nodiscard]] Vector GetIntegrationCoefficients() const; | ||
[[nodiscard]] Vector GetProjectedGravityForIntegrationPoints() const; | ||
[[nodiscard]] double GetMatrixScalarFactor() const; | ||
[[nodiscard]] Vector GetNodalValues(const Variable<double>& rVariable) const; | ||
|
||
private: | ||
std::function<const Properties&()> mGetElementProperties; | ||
std::function<const Matrix&()> mGetNContainer; | ||
std::function<Vector()> mGetIntegrationCoefficients; | ||
std::function<Vector()> mGetProjectedGravityForIntegrationPoints; | ||
std::function<double()> mGetMatrixScalarFactor; | ||
std::function<Vector(const Variable<double>&)> mGetNodalValues; | ||
}; | ||
|
||
explicit FilterCompressibilityCalculator(InputProvider AnInputProvider); | ||
|
||
Matrix LHSContribution() override; | ||
Vector RHSContribution() override; | ||
std::pair<Matrix, Vector> LocalSystemContribution() override; | ||
|
||
private: | ||
[[nodiscard]] Matrix CalculateCompressibilityMatrix() const; | ||
[[nodiscard]] double CalculateElasticCapacity(double ProjectedGravity) const; | ||
[[nodiscard]] Vector RHSContribution(const Matrix& rCompressibilityMatrix) const; | ||
[[nodiscard]] Matrix LHSContribution(const Matrix& rCompressibilityMatrix) const; | ||
|
||
InputProvider mInputProvider; | ||
}; | ||
|
||
} // namespace Kratos |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ | |
#include "custom_retention/retention_law_factory.h" | ||
#include "custom_utilities/dof_utilities.h" | ||
#include "custom_utilities/element_utilities.hpp" | ||
#include "filter_compressibility_calculator.h" | ||
#include "geo_mechanics_application_variables.h" | ||
#include "includes/cfd_variables.h" | ||
#include "includes/element.h" | ||
|
@@ -252,57 +253,70 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem | |
|
||
const auto integration_coefficients = CalculateIntegrationCoefficients(det_J_container); | ||
|
||
const std::size_t number_integration_points = | ||
GetGeometry().IntegrationPointsNumber(GetIntegrationMethod()); | ||
GeometryType::JacobiansType J_container; | ||
J_container.resize(number_integration_points, false); | ||
for (std::size_t i = 0; i < number_integration_points; ++i) { | ||
J_container[i].resize(GetGeometry().WorkingSpaceDimension(), | ||
GetGeometry().LocalSpaceDimension(), false); | ||
} | ||
GetGeometry().Jacobian(J_container, this->GetIntegrationMethod()); | ||
|
||
const auto& r_properties = GetProperties(); | ||
BoundedMatrix<double, 1, 1> constitutive_matrix; | ||
GeoElementUtilities::FillPermeabilityMatrix(constitutive_matrix, r_properties); | ||
|
||
RetentionLaw::Parameters RetentionParameters(GetProperties()); | ||
|
||
array_1d<double, TNumNodes * TDim> volume_acceleration; | ||
GeoElementUtilities::GetNodalVariableVector<TDim, TNumNodes>( | ||
volume_acceleration, GetGeometry(), VOLUME_ACCELERATION); | ||
const auto projected_gravity = CalculateProjectedGravityAtIntegrationPoints(N_container); | ||
|
||
array_1d<double, TNumNodes> fluid_body_vector = ZeroVector(TNumNodes); | ||
for (unsigned int integration_point_index = 0; | ||
integration_point_index < GetGeometry().IntegrationPointsNumber(GetIntegrationMethod()); | ||
++integration_point_index) { | ||
array_1d<double, TDim> body_acceleration; | ||
GeoElementUtilities::InterpolateVariableWithComponents<TDim, TNumNodes>( | ||
body_acceleration, N_container, volume_acceleration, integration_point_index); | ||
|
||
array_1d<double, TDim> tangent_vector = column(J_container[integration_point_index], 0); | ||
tangent_vector /= norm_2(tangent_vector); | ||
|
||
array_1d<double, 1> projected_gravity = ZeroVector(1); | ||
projected_gravity(0) = MathUtils<double>::Dot(tangent_vector, body_acceleration); | ||
const auto N = Vector{row(N_container, integration_point_index)}; | ||
const auto N = Vector{row(N_container, integration_point_index)}; | ||
double RelativePermeability = | ||
mRetentionLawVector[integration_point_index]->CalculateRelativePermeability(RetentionParameters); | ||
fluid_body_vector += | ||
r_properties[DENSITY_WATER] * RelativePermeability * | ||
prod(prod(shape_function_gradients[integration_point_index], constitutive_matrix), projected_gravity) * | ||
prod(prod(shape_function_gradients[integration_point_index], constitutive_matrix), | ||
ScalarVector(1, projected_gravity[integration_point_index])) * | ||
integration_coefficients[integration_point_index] / r_properties[DYNAMIC_VISCOSITY]; | ||
} | ||
return fluid_body_vector; | ||
} | ||
|
||
Vector CalculateProjectedGravityAtIntegrationPoints(const Matrix& rNContainer) const | ||
{ | ||
const auto number_integration_points = GetGeometry().IntegrationPointsNumber(GetIntegrationMethod()); | ||
GeometryType::JacobiansType J_container{number_integration_points}; | ||
for (std::size_t i = 0; i < number_integration_points; ++i) { | ||
J_container[i].resize(GetGeometry().WorkingSpaceDimension(), | ||
GetGeometry().LocalSpaceDimension(), false); | ||
} | ||
Comment on lines
+284
to
+287
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably Sonar Cloud will give a remark about this that can be avoided as follows: |
||
GetGeometry().Jacobian(J_container, this->GetIntegrationMethod()); | ||
|
||
array_1d<double, TNumNodes * TDim> volume_acceleration; | ||
GeoElementUtilities::GetNodalVariableVector<TDim, TNumNodes>( | ||
volume_acceleration, GetGeometry(), VOLUME_ACCELERATION); | ||
array_1d<double, TDim> body_acceleration; | ||
mnabideltares marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Vector projected_gravity = ZeroVector(number_integration_points); | ||
|
||
for (unsigned int integration_point_index = 0; | ||
integration_point_index < number_integration_points; ++integration_point_index) { | ||
GeoElementUtilities::InterpolateVariableWithComponents<TDim, TNumNodes>( | ||
body_acceleration, rNContainer, volume_acceleration, integration_point_index); | ||
array_1d<double, TDim> tangent_vector = column(J_container[integration_point_index], 0); | ||
tangent_vector /= norm_2(tangent_vector); | ||
projected_gravity(integration_point_index) = | ||
MathUtils<>::Dot(tangent_vector, body_acceleration); | ||
} | ||
return projected_gravity; | ||
} | ||
|
||
std::unique_ptr<ContributionCalculator> CreateCalculator(const CalculationContribution& rContribution, | ||
const ProcessInfo& rCurrentProcessInfo) | ||
{ | ||
switch (rContribution) { | ||
case CalculationContribution::Permeability: | ||
return std::make_unique<PermeabilityCalculator>(CreatePermeabilityInputProvider()); | ||
case CalculationContribution::Compressibility: | ||
if (GetProperties()[RETENTION_LAW] == "PressureFilterLaw") { | ||
return std::make_unique<FilterCompressibilityCalculator>( | ||
CreateFilterCompressibilityInputProvider(rCurrentProcessInfo)); | ||
} | ||
return std::make_unique<CompressibilityCalculator>(CreateCompressibilityInputProvider(rCurrentProcessInfo)); | ||
default: | ||
KRATOS_ERROR << "Unknown contribution" << std::endl; | ||
|
@@ -317,6 +331,14 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem | |
MakeNodalVariableGetter()); | ||
} | ||
|
||
FilterCompressibilityCalculator::InputProvider CreateFilterCompressibilityInputProvider(const ProcessInfo& rCurrentProcessInfo) | ||
{ | ||
return FilterCompressibilityCalculator::InputProvider( | ||
MakePropertiesGetter(), MakeNContainerGetter(), MakeIntegrationCoefficientsGetter(), | ||
MakeProjectedGravityForIntegrationPointsGetter(), | ||
MakeMatrixScalarFactorGetter(rCurrentProcessInfo), MakeNodalVariableGetter()); | ||
} | ||
|
||
PermeabilityCalculator::InputProvider CreatePermeabilityInputProvider() | ||
{ | ||
return PermeabilityCalculator::InputProvider( | ||
|
@@ -350,6 +372,14 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem | |
}; | ||
} | ||
|
||
auto MakeProjectedGravityForIntegrationPointsGetter() | ||
{ | ||
return [this]() -> Vector { | ||
return CalculateProjectedGravityAtIntegrationPoints( | ||
GetGeometry().ShapeFunctionsValues(GetIntegrationMethod())); | ||
}; | ||
} | ||
|
||
static auto MakeMatrixScalarFactorGetter(const ProcessInfo& rCurrentProcessInfo) | ||
{ | ||
return [&rCurrentProcessInfo]() { return rCurrentProcessInfo[DT_PRESSURE_COEFFICIENT]; }; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,7 +35,12 @@ void GeoElementUtilities::FillPermeabilityMatrix(BoundedMatrix<double, 1, 1>& | |
const Element::PropertiesType& Prop) | ||
{ | ||
// 1D | ||
rPermeabilityMatrix(0, 0) = Prop[PERMEABILITY_XX]; | ||
if (Prop[RETENTION_LAW] == "PressureFilterLaw") { | ||
const double equivalent_radius_square = Prop[CROSS_AREA] / Globals::Pi; | ||
rPermeabilityMatrix(0, 0) = equivalent_radius_square * 0.125; | ||
Comment on lines
+39
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would not expect the 'FillPermeabilityMatrix' function to perform a calculation here ( |
||
} else { | ||
rPermeabilityMatrix(0, 0) = Prop[PERMEABILITY_XX]; | ||
} | ||
} | ||
|
||
void GeoElementUtilities::FillPermeabilityMatrix(BoundedMatrix<double, 2, 2>& rPermeabilityMatrix, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not:
return 1.0 / (r_properties[DENSITY_WATER] * ProjectedGravity * r_properties[FILTER_LENGTH]) +
1.0 / r_properties[BULK_MODULUS_FLUID];
There is no need for the intermediate variable result.