Skip to content

Commit 8e37b28

Browse files
Merge branch 'master' into scripts/docker/update-rocky-python-
2 parents fde61bf + 992b518 commit 8e37b28

7 files changed

Lines changed: 133 additions & 57 deletions

File tree

applications/GeoMechanicsApplication/custom_elements/interface_element.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,11 @@ void InterfaceElement::Initialize(const ProcessInfo& rCurrentProcessInfo)
198198
std::vector<std::optional<Vector>> interface_nodal_cauchy_stresses(interface_node_ids.size());
199199
auto& r_neighbour_element = this->GetValue(NEIGHBOUR_ELEMENTS).front();
200200
std::vector<Vector> neighbour_cauchy_stresses;
201+
// Note that the interface elements don't account for water pressures yet. Consequently,
202+
// we need to consider the total stresses rather than the effective stresses to calculate
203+
// the appropriate prestresses to be applied.
201204
r_neighbour_element.CalculateOnIntegrationPoints(
202-
CAUCHY_STRESS_VECTOR, neighbour_cauchy_stresses, rCurrentProcessInfo);
205+
TOTAL_STRESS_VECTOR, neighbour_cauchy_stresses, rCurrentProcessInfo);
203206
interface_nodal_cauchy_stresses = ExtrapolationUtilities::CalculateNodalVectors(
204207
interface_node_ids, r_neighbour_element.GetGeometry(), r_neighbour_element.GetIntegrationMethod(),
205208
neighbour_cauchy_stresses, r_neighbour_element.Id());

applications/GeoMechanicsApplication/tests/cpp_tests/custom_elements/test_interface_element.cpp

Lines changed: 120 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "custom_constitutive/interface_plane_strain.h"
1717
#include "custom_constitutive/interface_three_dimensional_surface.h"
1818
#include "custom_constitutive/plane_strain.h"
19+
#include "custom_constitutive/three_dimensional.h"
1920
#include "custom_elements/interface_element.h"
2021
#include "custom_elements/interface_stress_state.h"
2122
#include "custom_geometries/interface_geometry.h"
@@ -311,6 +312,75 @@ Matrix ExpectedLeftHandSideForTriangleElement()
311312
return expected_left_hand_side;
312313
}
313314

315+
class MockElementWithTotalStressVectors : public Element
316+
{
317+
public:
318+
MockElementWithTotalStressVectors(std::size_t ElementId,
319+
std::shared_ptr<Geometry<Node>> pGeometry,
320+
Properties::Pointer pProperties);
321+
322+
void SetValuesOnIntegrationPoints(const Variable<Vector>& rVariable,
323+
const std::vector<Vector>& rValues,
324+
const ProcessInfo&) override;
325+
using Element::SetValuesOnIntegrationPoints;
326+
327+
void CalculateOnIntegrationPoints(const Variable<Vector>& rVariable,
328+
std::vector<Vector>& rOutput,
329+
const ProcessInfo&) override;
330+
using Element::CalculateOnIntegrationPoints;
331+
332+
IntegrationMethod GetIntegrationMethod() const override;
333+
void SetIntegrationMethod(IntegrationMethod CustomIntegrationMethod);
334+
335+
private:
336+
std::vector<Vector> mTotalStressVectors;
337+
std::optional<IntegrationMethod> mOptionalCustomIntegrationMethod;
338+
};
339+
340+
MockElementWithTotalStressVectors::MockElementWithTotalStressVectors(std::size_t ElementId,
341+
std::shared_ptr<Geometry<Node>> pGeometry,
342+
Properties::Pointer pProperties)
343+
: Element{ElementId, std::move(pGeometry), std::move(pProperties)}
344+
{
345+
}
346+
347+
void MockElementWithTotalStressVectors::SetValuesOnIntegrationPoints(const Variable<Vector>& rVariable,
348+
const std::vector<Vector>& rValues,
349+
const ProcessInfo&)
350+
{
351+
KRATOS_DEBUG_ERROR_IF_NOT(rVariable == TOTAL_STRESS_VECTOR)
352+
<< "This mock element can only set total stress vectors\n";
353+
354+
mTotalStressVectors = rValues;
355+
}
356+
357+
void MockElementWithTotalStressVectors::CalculateOnIntegrationPoints(const Variable<Vector>& rVariable,
358+
std::vector<Vector>& rOutput,
359+
const ProcessInfo&)
360+
{
361+
KRATOS_DEBUG_ERROR_IF_NOT(rVariable == TOTAL_STRESS_VECTOR)
362+
<< "This mock element can only calculate total stress vectors\n";
363+
364+
rOutput = mTotalStressVectors;
365+
}
366+
367+
GeometryData::IntegrationMethod MockElementWithTotalStressVectors::GetIntegrationMethod() const
368+
{
369+
return mOptionalCustomIntegrationMethod.value_or(GetGeometry().GetDefaultIntegrationMethod());
370+
}
371+
372+
void MockElementWithTotalStressVectors::SetIntegrationMethod(IntegrationMethod CustomIntegrationMethod)
373+
{
374+
mOptionalCustomIntegrationMethod = CustomIntegrationMethod;
375+
}
376+
377+
template <typename DerivedElementPtrType>
378+
GlobalPointersVector<Element> MakeElementGlobalPtrContainerWith(const DerivedElementPtrType& rpElement)
379+
{
380+
auto p_element = Element::Pointer{rpElement};
381+
return {{GlobalPointer<Element>{p_element}}};
382+
}
383+
314384
} // namespace
315385

316386
namespace Kratos::Testing
@@ -1314,18 +1384,20 @@ KRATOS_TEST_CASE_IN_SUITE(LineInterfaceElement_InterpolatesNodalStresses, Kratos
13141384
p_properties->SetValue(YOUNG_MODULUS, 1.000000e+07);
13151385
p_properties->SetValue(POISSON_RATIO, 0.000000e+00);
13161386
// create a triangle neighbour element
1317-
auto p_neighbour_element = ElementSetupUtilities::Create2D3NElement(nodes, p_properties, 2);
1387+
auto p_neighbour_element = make_intrusive<MockElementWithTotalStressVectors>(
1388+
2, std::make_shared<Triangle2D3<Node>>(nodes), p_properties);
1389+
p_neighbour_element->SetIntegrationMethod(GeometryData::IntegrationMethod::GI_GAUSS_2);
13181390
ProcessInfo dummy_process_info;
13191391
p_neighbour_element->Initialize(dummy_process_info);
1320-
std::vector<ConstitutiveLaw::StressVectorType> r_stress_vectors;
1392+
std::vector<ConstitutiveLaw::StressVectorType> total_stress_vectors;
13211393
ConstitutiveLaw::StressVectorType stress_vector(4);
13221394
stress_vector <<= 3.0, 13.0 / 6.0, 4.0, 1.0;
1323-
r_stress_vectors.emplace_back(stress_vector);
1324-
r_stress_vectors.emplace_back(stress_vector);
1395+
total_stress_vectors.emplace_back(stress_vector);
1396+
total_stress_vectors.emplace_back(stress_vector);
13251397
stress_vector <<= 3.0, 8.0 / 3.0, 4.0, 1.0;
1326-
r_stress_vectors.emplace_back(stress_vector);
1398+
total_stress_vectors.emplace_back(stress_vector);
13271399

1328-
p_neighbour_element->SetValuesOnIntegrationPoints(CAUCHY_STRESS_VECTOR, r_stress_vectors, dummy_process_info);
1400+
p_neighbour_element->SetValuesOnIntegrationPoints(TOTAL_STRESS_VECTOR, total_stress_vectors, dummy_process_info);
13291401

13301402
nodes.clear();
13311403
nodes.push_back(r_model_part.pGetNode(1));
@@ -1338,8 +1410,7 @@ KRATOS_TEST_CASE_IN_SUITE(LineInterfaceElement_InterpolatesNodalStresses, Kratos
13381410
const auto p_interface_properties =
13391411
CreateElasticMaterialProperties<InterfacePlaneStrain>(normal_stiffness, shear_stiffness);
13401412
auto interface_element = CreateInterfaceElementWithUDofs<Interface2D>(p_interface_properties, p_geometry);
1341-
GlobalPointersVector<Element> neighbours{p_neighbour_element};
1342-
interface_element.SetValue(NEIGHBOUR_ELEMENTS, neighbours);
1413+
interface_element.SetValue(NEIGHBOUR_ELEMENTS, MakeElementGlobalPtrContainerWith(p_neighbour_element));
13431414

13441415
// Act
13451416
interface_element.Initialize(dummy_process_info);
@@ -1359,20 +1430,20 @@ KRATOS_TEST_CASE_IN_SUITE(LineInterfaceElement_InterpolatesNodalStresses, Kratos
13591430
nodes.push_back(r_model_part.pGetNode(4));
13601431
nodes.push_back(r_model_part.pGetNode(5));
13611432
nodes.push_back(r_model_part.CreateNewNode(6, 0.0, 2.0, 0.0));
1362-
auto p_other_neighbour_element = ElementSetupUtilities::Create2D3NElement(nodes, p_properties, 3);
1433+
auto p_other_neighbour_element = make_intrusive<MockElementWithTotalStressVectors>(
1434+
3, std::make_shared<Triangle2D3<Node>>(nodes), p_properties);
1435+
p_other_neighbour_element->SetIntegrationMethod(GeometryData::IntegrationMethod::GI_GAUSS_2);
13631436
p_other_neighbour_element->Initialize(dummy_process_info);
1364-
r_stress_vectors.clear();
1437+
total_stress_vectors.clear();
13651438
stress_vector <<= 7.0, 4.0, 11.0, 5.0 / 6.0;
1366-
r_stress_vectors.emplace_back(stress_vector);
1439+
total_stress_vectors.emplace_back(stress_vector);
13671440
stress_vector <<= 7.0, 4.0, 11.0, 10.0 / 3.0;
1368-
r_stress_vectors.emplace_back(stress_vector);
1441+
total_stress_vectors.emplace_back(stress_vector);
13691442
stress_vector <<= 7.0, 4.0, 11.0, 5.0 / 6.0;
1370-
r_stress_vectors.emplace_back(stress_vector);
1371-
p_other_neighbour_element->SetValuesOnIntegrationPoints(CAUCHY_STRESS_VECTOR, r_stress_vectors,
1372-
dummy_process_info);
1373-
1374-
GlobalPointersVector<Element> other_neighbours{p_other_neighbour_element};
1375-
interface_element.SetValue(NEIGHBOUR_ELEMENTS, other_neighbours);
1443+
total_stress_vectors.emplace_back(stress_vector);
1444+
p_other_neighbour_element->SetValuesOnIntegrationPoints(
1445+
TOTAL_STRESS_VECTOR, total_stress_vectors, dummy_process_info);
1446+
interface_element.SetValue(NEIGHBOUR_ELEMENTS, MakeElementGlobalPtrContainerWith(p_other_neighbour_element));
13761447

13771448
// Act
13781449
interface_element.Initialize(dummy_process_info);
@@ -1404,27 +1475,29 @@ KRATOS_TEST_CASE_IN_SUITE(PlaneInterfaceElement_InterpolatesNodalStresses, Krato
14041475
// properties for neighbour elements
14051476
const auto p_properties = std::make_shared<Properties>();
14061477
p_properties->SetValue(CONSTITUTIVE_LAW, std::make_shared<GeoIncrementalLinearElasticLaw>(
1407-
std::make_unique<PlaneStrain>()));
1478+
std::make_unique<ThreeDimensional>()));
14081479
p_properties->SetValue(YOUNG_MODULUS, 1.000000e+07);
14091480
p_properties->SetValue(POISSON_RATIO, 0.000000e+00);
14101481
// create a hexagonal neighbour element
1411-
auto p_neighbour_element = ElementSetupUtilities::Create3D8NElement(nodes, p_properties, 2);
1482+
auto p_neighbour_element = make_intrusive<MockElementWithTotalStressVectors>(
1483+
2, std::make_shared<Hexahedra3D8<Node>>(nodes), p_properties);
1484+
p_neighbour_element->SetIntegrationMethod(GeometryData::IntegrationMethod::GI_GAUSS_2);
14121485

14131486
ProcessInfo dummy_process_info;
14141487
p_neighbour_element->Initialize(dummy_process_info);
1415-
std::vector<ConstitutiveLaw::StressVectorType> r_stress_vectors;
1488+
std::vector<ConstitutiveLaw::StressVectorType> total_stress_vectors;
14161489
ConstitutiveLaw::StressVectorType stress_vector(6);
14171490
stress_vector <<= 3.0, (std::sqrt(3.0) - 1.0) / (2.0 * std::sqrt(3.0)), 4.0, 1.0, 2.0, 4.0;
1418-
r_stress_vectors.emplace_back(stress_vector);
1419-
r_stress_vectors.emplace_back(stress_vector);
1420-
r_stress_vectors.emplace_back(stress_vector);
1421-
r_stress_vectors.emplace_back(stress_vector);
1491+
total_stress_vectors.emplace_back(stress_vector);
1492+
total_stress_vectors.emplace_back(stress_vector);
1493+
total_stress_vectors.emplace_back(stress_vector);
1494+
total_stress_vectors.emplace_back(stress_vector);
14221495
stress_vector <<= 3.0, (std::sqrt(3.0) + 1.0) / (2.0 * std::sqrt(3.0)), 4.0, 1.0, 2.0, 4.0;
1423-
r_stress_vectors.emplace_back(stress_vector);
1424-
r_stress_vectors.emplace_back(stress_vector);
1425-
r_stress_vectors.emplace_back(stress_vector);
1426-
r_stress_vectors.emplace_back(stress_vector);
1427-
p_neighbour_element->SetValuesOnIntegrationPoints(CAUCHY_STRESS_VECTOR, r_stress_vectors, dummy_process_info);
1496+
total_stress_vectors.emplace_back(stress_vector);
1497+
total_stress_vectors.emplace_back(stress_vector);
1498+
total_stress_vectors.emplace_back(stress_vector);
1499+
total_stress_vectors.emplace_back(stress_vector);
1500+
p_neighbour_element->SetValuesOnIntegrationPoints(TOTAL_STRESS_VECTOR, total_stress_vectors, dummy_process_info);
14281501

14291502
nodes.clear();
14301503
nodes.push_back(r_model_part.pGetNode(2));
@@ -1441,8 +1514,7 @@ KRATOS_TEST_CASE_IN_SUITE(PlaneInterfaceElement_InterpolatesNodalStresses, Krato
14411514
const auto p_interface_properties =
14421515
CreateElasticMaterialProperties<InterfaceThreeDimensionalSurface>(normal_stiffness, shear_stiffness);
14431516
auto interface_element = CreateInterfaceElementWithUDofs<Interface3D>(p_interface_properties, p_geometry);
1444-
GlobalPointersVector<Element> neighbours{p_neighbour_element};
1445-
interface_element.SetValue(NEIGHBOUR_ELEMENTS, neighbours);
1517+
interface_element.SetValue(NEIGHBOUR_ELEMENTS, MakeElementGlobalPtrContainerWith(p_neighbour_element));
14461518

14471519
// Act
14481520
interface_element.Initialize(dummy_process_info);
@@ -1471,24 +1543,25 @@ KRATOS_TEST_CASE_IN_SUITE(PlaneInterfaceElement_InterpolatesNodalStresses, Krato
14711543
nodes.push_back(r_model_part.CreateNewNode(16, 0.5, 1.5, 1.0));
14721544
nodes.push_back(r_model_part.CreateNewNode(17, -0.5, 1.5, 1.0));
14731545
nodes.push_back(r_model_part.pGetNode(18));
1474-
auto p_other_neighbour_element = ElementSetupUtilities::Create3D8NElement(nodes, p_properties, 3);
1546+
auto p_other_neighbour_element = make_intrusive<MockElementWithTotalStressVectors>(
1547+
3, std::make_shared<Hexahedra3D8<Node>>(nodes), p_properties);
1548+
p_neighbour_element->SetIntegrationMethod(GeometryData::IntegrationMethod::GI_GAUSS_2);
14751549
p_other_neighbour_element->Initialize(dummy_process_info);
1476-
r_stress_vectors.clear();
1550+
total_stress_vectors.clear();
14771551
stress_vector <<= 3.0, 4.0, 1.0, 2.0, (std::sqrt(3.0) - 1.0) / (2.0 * std::sqrt(3.0)), 4.0;
1478-
r_stress_vectors.emplace_back(stress_vector);
1479-
r_stress_vectors.emplace_back(stress_vector);
1480-
r_stress_vectors.emplace_back(stress_vector);
1481-
r_stress_vectors.emplace_back(stress_vector);
1552+
total_stress_vectors.emplace_back(stress_vector);
1553+
total_stress_vectors.emplace_back(stress_vector);
1554+
total_stress_vectors.emplace_back(stress_vector);
1555+
total_stress_vectors.emplace_back(stress_vector);
14821556
stress_vector <<= 3.0, 4.0, 1.0, 2.0, (std::sqrt(3.0) + 1.0) / (2.0 * std::sqrt(3.0)), 4.0;
1483-
r_stress_vectors.emplace_back(stress_vector);
1484-
r_stress_vectors.emplace_back(stress_vector);
1485-
r_stress_vectors.emplace_back(stress_vector);
1486-
r_stress_vectors.emplace_back(stress_vector);
1487-
p_other_neighbour_element->SetValuesOnIntegrationPoints(CAUCHY_STRESS_VECTOR, r_stress_vectors,
1488-
dummy_process_info);
1489-
1490-
GlobalPointersVector<Element> other_neighbours{p_other_neighbour_element};
1491-
interface_element.SetValue(NEIGHBOUR_ELEMENTS, other_neighbours);
1557+
total_stress_vectors.emplace_back(stress_vector);
1558+
total_stress_vectors.emplace_back(stress_vector);
1559+
total_stress_vectors.emplace_back(stress_vector);
1560+
total_stress_vectors.emplace_back(stress_vector);
1561+
p_other_neighbour_element->SetValuesOnIntegrationPoints(
1562+
TOTAL_STRESS_VECTOR, total_stress_vectors, dummy_process_info);
1563+
1564+
interface_element.SetValue(NEIGHBOUR_ELEMENTS, MakeElementGlobalPtrContainerWith(p_other_neighbour_element));
14921565

14931566
// Act
14941567
interface_element.Initialize(dummy_process_info);

applications/GeoMechanicsApplication/tests/test_interface_prestress/MaterialParameters.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"Variables": {
1010
"IGNORE_UNDRAINED" : true,
11-
"YOUNG_MODULUS" : 120.0e6,
11+
"YOUNG_MODULUS" : 1.0e4,
1212
"POISSON_RATIO" : 0.0,
1313
"DENSITY_SOLID" : 0.0,
1414
"DENSITY_WATER" : 1.0e3,
@@ -29,8 +29,8 @@
2929
"name" : "GeoIncrementalLinearElasticInterfaceLaw"
3030
},
3131
"Variables": {
32-
"INTERFACE_NORMAL_STIFFNESS": 480.0e6,
33-
"INTERFACE_SHEAR_STIFFNESS": 200.0e6
32+
"INTERFACE_NORMAL_STIFFNESS": 2.0e3,
33+
"INTERFACE_SHEAR_STIFFNESS": 1.0e3
3434
}
3535
}
3636
}]

applications/GeoMechanicsApplication/tests/test_interface_prestress/ProjectParameters_stage1.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
"variable_name": "WATER_PRESSURE",
8686
"active": true,
8787
"is_fixed": true,
88-
"value": 0.0,
88+
"value": -250.0,
8989
"table": 0
9090
}
9191
},

applications/GeoMechanicsApplication/tests/test_interface_prestress/ProjectParameters_stage2.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
"variable_name": "WATER_PRESSURE",
9898
"active": true,
9999
"is_fixed": true,
100-
"value": 0.0,
100+
"value": -250.0,
101101
"table": 0
102102
}
103103
}

applications/GeoMechanicsApplication/tests/test_interface_prestress/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ o---o---o
4646
Next to the aforementioned elements and top load, the following constraints are applied:
4747
- The bottom nodes of the continuum elements are fixed in all directions.
4848
- The side nodes are fixed in the horizontal direction.
49-
- The water pressure is kept at zero in the entire domain.
49+
- The water pressure is kept at -250.0 Pa in the entire domain (to verify that the effect it has on the prestress calculation is properly taken into account).
5050

5151
A linear elastic material is used for both the continuum and the interface elements.
5252

5353
## Assertions
5454

5555
The following assertions are done to validate the prestress functionality:
5656
- In the second stage, all stage displacements of the nodes are checked to be zero (within a small tolerance). This would not be the case if the interfaces were not prestressed based on the first stage stresses in the continuum elements.
57-
- The stresses at the integration points of the interface elements are checked to be equal to the expected stresses at the integration points of the neighbouring continuum element. These are expected to be 1 kPa in the normal direction (following from the vertical equilibrium) and zero in the shear direction.
57+
- The traction components at the integration points of the interface elements are checked to be equal to the corresponding stress components at the integration points of the neighbouring continuum element. These are expected to be 1 kPa in the normal direction (following from the vertical equilibrium) and zero in the shear direction.
5858
- The relative (normal and shear) displacements of the interface elements are checked to be zero (within a small tolerance).

applications/OptimizationApplication/python_scripts/convergence_criteria/l2_conv_criterion.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import typing
2-
import numpy
32
import KratosMultiphysics as Kratos
3+
import KratosMultiphysics.OptimizationApplication as KratosOA
44
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem
55
from KratosMultiphysics.OptimizationApplication.utilities.component_data_view import ComponentDataView
66
from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem_utilities import GetComponentHavingDataByFullName
@@ -57,7 +57,7 @@ def IsConverged(self) -> bool:
5757
if not hasattr(field, "Evaluate"):
5858
raise RuntimeError(f"The value represented by {self.__field_name} is not a field.")
5959

60-
self.__norm = numpy.linalg.norm(field.Evaluate().flatten())
60+
self.__norm = KratosOA.ExpressionUtils.NormL2(field)
6161
self.__conv = self.__norm <= self.__tolerance
6262
self.__component_data_view.GetBufferedData().SetValue(self.__field_name.split(':')[0] + "_l2_norm", self.__norm)
6363
return self.__conv

0 commit comments

Comments
 (0)