Skip to content
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

[DEMApplication] New linear contact force model #13008

Merged
merged 10 commits into from
Jan 19, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions applications/DEMApplication/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ set(KRATOS_DEM_APPLICATION_CORE
${CMAKE_CURRENT_SOURCE_DIR}/custom_constitutive/DEM_KDEM_CamClay_CL.cpp
${CMAKE_CURRENT_SOURCE_DIR}/custom_constitutive/dem_kdem_fissured_rock_cl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/custom_constitutive/DEM_ExponentialHC_CL.cpp
${CMAKE_CURRENT_SOURCE_DIR}/custom_constitutive/DEM_D_Linear_Simple_Coulomb_CL.cpp
${CMAKE_CURRENT_SOURCE_DIR}/custom_constitutive/DEM_D_Linear_viscous_Coulomb_CL.cpp
${CMAKE_CURRENT_SOURCE_DIR}/custom_constitutive/DEM_D_Linear_HighStiffness_CL.cpp
${CMAKE_CURRENT_SOURCE_DIR}/custom_constitutive/DEM_D_Linear_HighStiffness_2D_CL.cpp
Expand Down
24 changes: 9 additions & 15 deletions applications/DEMApplication/DEM_application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "custom_constitutive/DEM_Dempack_dev_CL.h"
#include "custom_constitutive/dem_kdem_2d_cl.h"
#include "custom_constitutive/dem_kdem_fabric_2d_cl.h"
#include "custom_constitutive/DEM_D_Linear_Simple_Coulomb_CL.h"
#include "custom_constitutive/DEM_D_Linear_viscous_Coulomb_CL.h"
#include "custom_constitutive/DEM_D_Linear_viscous_Coulomb_2D_CL.h"
#include "custom_constitutive/DEM_D_Hertz_viscous_Coulomb_CL.h"
Expand Down Expand Up @@ -1034,28 +1035,21 @@ void KratosDEMApplication::Register() {
KRATOS_REGISTER_CONDITION("RigidEdge2D2N", mRigidEdge2D2N)
KRATOS_REGISTER_CONDITION("RigidEdge2D1N", mRigidEdge2D1N)


// SERIALIZER
Serializer::Register("PropertiesProxy", PropertiesProxy());

Serializer::Register(
"DEM_D_Linear_viscous_Coulomb", DEM_D_Linear_viscous_Coulomb());
Serializer::Register(
"DEM_D_Linear_viscous_Coulomb2D", DEM_D_Linear_viscous_Coulomb2D());
Serializer::Register(
"DEM_D_Hertz_viscous_Coulomb", DEM_D_Hertz_viscous_Coulomb());
Serializer::Register(
"DEM_D_Hertz_viscous_Coulomb2D", DEM_D_Hertz_viscous_Coulomb2D());
Serializer::Register("DEM_D_Linear_Simple_Coulomb", DEM_D_Linear_Simple_Coulomb());
Serializer::Register("DEM_D_Linear_viscous_Coulomb", DEM_D_Linear_viscous_Coulomb());
Serializer::Register("DEM_D_Linear_viscous_Coulomb2D", DEM_D_Linear_viscous_Coulomb2D());
Serializer::Register("DEM_D_Hertz_viscous_Coulomb", DEM_D_Hertz_viscous_Coulomb());
Serializer::Register("DEM_D_Hertz_viscous_Coulomb2D", DEM_D_Hertz_viscous_Coulomb2D());
Serializer::Register("DEM_D_JKR_Cohesive_Law", DEM_D_JKR_Cohesive_Law());
Serializer::Register("DEM_D_Bentonite_Colloid", DEM_D_Bentonite_Colloid());
Serializer::Register("DEM_D_DMT_Cohesive_Law", DEM_D_DMT_Cohesive_Law());
Serializer::Register("DEM_D_Stress_Dependent_Cohesive", DEM_D_Stress_Dependent_Cohesive());
Serializer::Register(
"DEM_D_Linear_Custom_Constants", DEM_D_Linear_Custom_Constants());
Serializer::Register(
"DEM_D_Conical_damage", DEM_D_Conical_damage());
Serializer::Register("DEM_D_Hertz_viscous_Coulomb_Nestle",
DEM_D_Hertz_viscous_Coulomb_Nestle());
Serializer::Register("DEM_D_Linear_Custom_Constants", DEM_D_Linear_Custom_Constants());
Serializer::Register("DEM_D_Conical_damage", DEM_D_Conical_damage());
Serializer::Register("DEM_D_Hertz_viscous_Coulomb_Nestle", DEM_D_Hertz_viscous_Coulomb_Nestle());
Serializer::Register("DEM_D_Quadratic", DEM_D_Quadratic());
Serializer::Register("DEM_D_Linear_classic", DEM_D_Linear_classic());
Serializer::Register("DEM_D_void", DEM_D_void());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Kratos Multi-Physics - DEM Application
//
// License: BSD License
// Kratos default license: kratos/license.txt
//
// Main authors: Rafael Rangel ([email protected])
//
// References using this model:
// R.L. Rangel et al. (2024). Multiscale data-driven modeling of the thermomechanical behavior of granular media with thermal expansion effects. Comput Geotech, 176:106789.
// R.L. Rangel et al. (2024). A continuum--discrete multiscale methodology using machine learning for thermal analysis of granular media. Comput Geotech, 168:106118.
// S. Zhao et al. (2020). Multiscale modeling of thermo-mechanical responses of granular materials: A hierarchical continuum--discrete coupling approach. CMAME, 367:113100.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the paper by Zhao, although they said that the simple linear contact model was used, they did not explicitly give the formulation about how to calculate the normal and tangential stiffness. Should this one be replaced with another piece of literature?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true. I changed the reference.

//

#include "DEM_D_Linear_Simple_Coulomb_CL.h"
#include "custom_elements/spheric_particle.h"

namespace Kratos {

DEMDiscontinuumConstitutiveLaw::Pointer DEM_D_Linear_Simple_Coulomb::Clone() const {
DEMDiscontinuumConstitutiveLaw::Pointer p_clone(new DEM_D_Linear_Simple_Coulomb(*this));
return p_clone;
}

std::unique_ptr<DEMDiscontinuumConstitutiveLaw> DEM_D_Linear_Simple_Coulomb::CloneUnique() {
return Kratos::make_unique<DEM_D_Linear_Simple_Coulomb>();
}

std::string DEM_D_Linear_Simple_Coulomb::GetTypeOfLaw() {
std::string type_of_law = "Linear";
return type_of_law;
}

void DEM_D_Linear_Simple_Coulomb::Check(Properties::Pointer pProp) const {
if (!pProp->Has(STATIC_FRICTION)) {
if (!pProp->Has(FRICTION)) { //deprecated since April 6th, 2020
KRATOS_WARNING("DEM") << std::endl;
KRATOS_WARNING("DEM") << "WARNING: Variable STATIC_FRICTION or FRICTION should be present in the properties when using DEMDiscontinuumConstitutiveLaw. 0.0 value assigned by default." << std::endl;
KRATOS_WARNING("DEM") << std::endl;
pProp->GetValue(STATIC_FRICTION) = 0.0;
}
else {
pProp->GetValue(STATIC_FRICTION) = pProp->GetValue(FRICTION);
}
}
}

void DEM_D_Linear_Simple_Coulomb::CalculateForces(const ProcessInfo& r_process_info,
const double OldLocalElasticContactForce[3],
double LocalElasticContactForce[3],
double LocalDeltDisp[3],
double LocalRelVel[3],
double indentation,
double previous_indentation,
double ViscoDampingLocalContactForce[3],
double& cohesive_force,
SphericParticle* element1,
SphericParticle* element2,
bool& sliding,
double LocalCoordSystem[3][3]) {
// Compute stiffness coefficients
const double my_radius = element1->GetRadius();
const double other_radius = element2->GetRadius();
const double equiv_radius = 2.0 * my_radius * other_radius / (my_radius + other_radius);
const double my_young = element1->GetYoung();
const double my_poisson = element1->GetPoisson();

mKn = my_young * equiv_radius; // normal
mKt = my_poisson * mKn; // tangent

// Compute normal and tangent forces
const double normal_contact_force = mKn * indentation;
LocalElasticContactForce[2] = normal_contact_force;

CalculateTangentialForceWithNeighbour(normal_contact_force, OldLocalElasticContactForce, LocalElasticContactForce, LocalDeltDisp, sliding, element1, element2);
}

void DEM_D_Linear_Simple_Coulomb::CalculateForcesWithFEM(const ProcessInfo& r_process_info,
const double OldLocalElasticContactForce[3],
double LocalElasticContactForce[3],
double LocalDeltDisp[3],
double LocalRelVel[3],
double indentation,
double previous_indentation,
double ViscoDampingLocalContactForce[3],
double& cohesive_force,
SphericParticle* const element,
Condition* const wall,
bool& sliding) {
// Compute stiffness coefficients
const double my_radius = element->GetRadius();
const double my_young = element->GetYoung();
const double my_poisson = element->GetPoisson();

mKn = my_young * my_radius; // normal
mKt = my_poisson * mKn; // tangent
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Rafael. In this line, you are calculating the tangential stiffness using the "poisson_ratio" from the particle. However, in both of your papers, you were using the item "tangential-to-normal stiffness ratio". To me, the physical significance of those two items is different.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zhao actually calls it the Poison ration. I decided to call it tangential-to-normal stiffness ratio in my papers exactly because it has a different physical meaning.


// Compute normal and tangent forces
const double normal_contact_force = mKn * indentation;
LocalElasticContactForce[2] = normal_contact_force;

CalculateTangentialForceWithNeighbour(normal_contact_force, OldLocalElasticContactForce, LocalElasticContactForce, LocalDeltDisp, sliding, element, wall);
}

template<class NeighbourClassType>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A template function is suggested to be put in the head file if I am right. Please look at this link.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true. Done it.

void DEM_D_Linear_Simple_Coulomb::CalculateTangentialForceWithNeighbour(const double normal_contact_force,
const double OldLocalElasticContactForce[3],
double LocalElasticContactForce[3],
const double LocalDeltDisp[3],
bool& sliding,
SphericParticle* const element,
NeighbourClassType* const neighbour) {
// Compute shear force
LocalElasticContactForce[0] = OldLocalElasticContactForce[0] - mKt * LocalDeltDisp[0];
LocalElasticContactForce[1] = OldLocalElasticContactForce[1] - mKt * LocalDeltDisp[1];
const double tangent_contact_force = sqrt(LocalElasticContactForce[0] * LocalElasticContactForce[0] + LocalElasticContactForce[1] * LocalElasticContactForce[1]);

// Compute maximum admisible shear force
Properties& properties_of_this_contact = element->GetProperties().GetSubProperties(neighbour->GetProperties().Id());
const double friction_angle_tg = std::tan(properties_of_this_contact[STATIC_FRICTION]);
const double MaximumAdmisibleShearForce = normal_contact_force * friction_angle_tg;

// Check for sliding: apply Coulomb friction condition
if (tangent_contact_force > MaximumAdmisibleShearForce) {
sliding = true;
const double fraction = MaximumAdmisibleShearForce / tangent_contact_force;
LocalElasticContactForce[0] *= fraction;
LocalElasticContactForce[1] *= fraction;
}
}

} // namespace Kratos
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Kratos Multi-Physics - DEM Application
//
// License: BSD License
// Kratos default license: kratos/license.txt
//
// Main authors: Rafael Rangel ([email protected])
//
// References using this model:
// R.L. Rangel et al. (2024). Multiscale data-driven modeling of the thermomechanical behavior of granular media with thermal expansion effects. Computers and Geotechnics, 176:106789.
// R.L. Rangel et al. (2024). A continuum--discrete multiscale methodology using machine learning for thermal analysis of granular media. Computers and Geotechnics, 168:106118.
// S. Zhao et al. (2020). Multiscale modeling of thermo-mechanical responses of granular materials: A hierarchical continuum--discrete coupling approach. CMAME, 367:113100.
//

#pragma once

#include <string>
#include "DEM_discontinuum_constitutive_law.h"

namespace Kratos {

class SphericParticle;
class KRATOS_API(DEM_APPLICATION) DEM_D_Linear_Simple_Coulomb : public DEMDiscontinuumConstitutiveLaw {

public:

using DEMDiscontinuumConstitutiveLaw::CalculateNormalForce;

KRATOS_CLASS_POINTER_DEFINITION(DEM_D_Linear_Simple_Coulomb);

DEM_D_Linear_Simple_Coulomb() {}
~DEM_D_Linear_Simple_Coulomb() {}

DEMDiscontinuumConstitutiveLaw::Pointer Clone() const override;
std::unique_ptr<DEMDiscontinuumConstitutiveLaw> CloneUnique() override;

std::string GetTypeOfLaw() override;
virtual void Check(Properties::Pointer pProp) const override;

void CalculateForces(const ProcessInfo& r_process_info,
const double OldLocalElasticContactForce[3],
double LocalElasticContactForce[3],
double LocalDeltDisp[3],
double LocalRelVel[3],
double indentation,
double previous_indentation,
double ViscoDampingLocalContactForce[3],
double& cohesive_force,
SphericParticle* element1,
SphericParticle* element2,
bool& sliding,
double LocalCoordSystem[3][3]) override;

void CalculateForcesWithFEM(const ProcessInfo& r_process_info,
const double OldLocalElasticContactForce[3],
double LocalElasticContactForce[3],
double LocalDeltDisp[3],
double LocalRelVel[3],
double indentation,
double previous_indentation,
double ViscoDampingLocalContactForce[3],
double& cohesive_force,
SphericParticle* const element,
Condition* const wall,
bool& sliding) override;

template <class NeighbourClassType>
void CalculateTangentialForceWithNeighbour(const double normal_contact_force,
const double OldLocalElasticContactForce[3],
double LocalElasticContactForce[3],
const double LocalDeltDisp[3],
bool& sliding,
SphericParticle* const element,
NeighbourClassType* const neighbour);

private:

friend class Serializer;

virtual void save(Serializer& rSerializer) const override {
KRATOS_SERIALIZE_SAVE_BASE_CLASS(rSerializer, DEMDiscontinuumConstitutiveLaw)
}

virtual void load(Serializer& rSerializer) override {
KRATOS_SERIALIZE_LOAD_BASE_CLASS(rSerializer, DEMDiscontinuumConstitutiveLaw)
}

};
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "custom_constitutive/DEM_compound_constitutive_law.h"
#include "custom_constitutive/DEM_compound_constitutive_law_for_PBM.h"

#include "custom_constitutive/DEM_D_Linear_Simple_Coulomb_CL.h"
#include "custom_constitutive/DEM_D_Linear_viscous_Coulomb_CL.h"
#include "custom_constitutive/DEM_D_Hertz_viscous_Coulomb_CL.h"
#include "custom_constitutive/DEM_D_Hertz_viscous_Coulomb_Nestle_CL.h"
Expand Down Expand Up @@ -97,6 +98,10 @@ void AddCustomConstitutiveLawsToPython(pybind11::module& m) {
.def(py::init<>())
;

py::class_<DEM_D_Linear_Simple_Coulomb, DEM_D_Linear_Simple_Coulomb::Pointer, DEMDiscontinuumConstitutiveLaw>(m, "DEM_D_Linear_Simple_Coulomb")
.def(py::init<>())
;

py::class_<DEM_D_Linear_viscous_Coulomb2D, DEM_D_Linear_viscous_Coulomb2D::Pointer, DEM_D_Linear_viscous_Coulomb>(m, "DEM_D_Linear_viscous_Coulomb2D")
.def(py::init<>())
;
Expand Down
Loading