https://mooseframework.inl.gov
Loading...
Searching...
No Matches
FrictionProjectionTest.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "gtest/gtest.h"
11
12#include "MortarContactUtils.h"
13#include "MathUtils.h"
14
15#include "metaphysicl/raw_type.h"
16
17#include <array>
18#include <cmath>
19
21
23
24template <typename T>
25class FrictionProjectionTest : public ::testing::Test
26{
27};
28
29using FrictionProjectionTypes = ::testing::Types<Real, ADReal>;
31
33{
34 using T = TypeParam;
35
36 const std::array<T, 1> stick_pressure = {1.0};
37 const std::array<T, 1> stick_augmented = {1.0};
38 const auto ac_stick =
39 ContactUtils::alartCurnierFrictionResidual(stick_pressure, stick_augmented, T(2.0));
40 const auto hsw_stick =
41 ContactUtils::hueberStadlerWohlmuthFrictionResidual(stick_pressure, stick_augmented, T(2.0));
42 EXPECT_DOUBLE_EQ(raw_value(ac_stick[0]), 0.0);
43 EXPECT_DOUBLE_EQ(raw_value(hsw_stick[0]), 0.0);
44
45 const std::array<T, 1> slip_pressure = {2.0};
46 const std::array<T, 1> slip_augmented = {4.0};
47 const auto ac_slip =
48 ContactUtils::alartCurnierFrictionResidual(slip_pressure, slip_augmented, T(2.0));
49 const auto hsw_slip =
50 ContactUtils::hueberStadlerWohlmuthFrictionResidual(slip_pressure, slip_augmented, T(2.0));
51 EXPECT_DOUBLE_EQ(raw_value(ac_slip[0]), 0.0);
52 EXPECT_DOUBLE_EQ(raw_value(hsw_slip[0]), 0.0);
53}
54
55TYPED_TEST(FrictionProjectionTest, SeparationAndAugmentedNormalSign)
56{
57 using T = TypeParam;
58
59 const T open_augmented_pressure = ContactUtils::augmentedNormalPressure(T(1.0), T(2.0));
60 EXPECT_DOUBLE_EQ(raw_value(open_augmented_pressure), -1.0);
61 EXPECT_DOUBLE_EQ(raw_value(ContactUtils::coulombFrictionRadius(T(0.5), open_augmented_pressure)),
62 0.0);
63
64 const std::array<T, 1> pressure = {0.0};
65 const std::array<T, 1> augmented_pressure = {3.0};
66 const auto ac = ContactUtils::alartCurnierFrictionResidual(pressure, augmented_pressure, T(0.0));
67 const auto hsw =
68 ContactUtils::hueberStadlerWohlmuthFrictionResidual(pressure, augmented_pressure, T(0.0));
69 EXPECT_DOUBLE_EQ(raw_value(ac[0]), 0.0);
70 EXPECT_DOUBLE_EQ(raw_value(hsw[0]), 0.0);
71}
72
73TYPED_TEST(FrictionProjectionTest, ThreeDimensionalProjection)
74{
75 using T = TypeParam;
76
77 const std::array<T, 2> augmented_pressure = {3.0, 4.0};
78 const auto projection = ContactUtils::projectToClosedSphere(augmented_pressure, T(2.0));
79 EXPECT_DOUBLE_EQ(raw_value(projection[0]), 1.2);
80 EXPECT_DOUBLE_EQ(raw_value(projection[1]), 1.6);
81 EXPECT_DOUBLE_EQ(raw_value(MathUtils::norm(projection)), 2.0);
82}
83
85{
86 using T = TypeParam;
87
88 const std::array<T, 2> pressure = {0.7, -0.2};
89 const std::array<T, 2> augmented_pressure = {2.0, -1.0};
90 const T radius = 0.8;
91 const T alpha = 3.0;
92 const std::array<T, 2> scaled_pressure = {alpha * pressure[0], alpha * pressure[1]};
93 const std::array<T, 2> scaled_augmented = {alpha * augmented_pressure[0],
94 alpha * augmented_pressure[1]};
95
96 const auto ac = ContactUtils::alartCurnierFrictionResidual(pressure, augmented_pressure, radius);
97 const auto ac_scaled =
98 ContactUtils::alartCurnierFrictionResidual(scaled_pressure, scaled_augmented, alpha * radius);
99 const auto hsw =
100 ContactUtils::hueberStadlerWohlmuthFrictionResidual(pressure, augmented_pressure, radius);
102 scaled_pressure, scaled_augmented, alpha * radius);
103
104 for (const auto i : index_range(pressure))
105 {
106 EXPECT_NEAR(raw_value(ac_scaled[i]), raw_value(alpha * ac[i]), 1e-14);
107 EXPECT_NEAR(raw_value(hsw_scaled[i]), raw_value(alpha * alpha * hsw[i]), 1e-14);
108 }
109}
110
111TYPED_TEST(FrictionProjectionTest, PositiveWeightRelationship)
112{
113 using T = TypeParam;
114
115 const std::array<T, 2> pressure = {0.6, -0.1};
116 const std::array<T, 2> augmented_pressure = {1.5, -0.5};
117 const T radius = 0.9;
118 const T weight = std::max(radius, MathUtils::norm(augmented_pressure));
119 ASSERT_GT(raw_value(weight), 0.0);
120
121 const auto ac = ContactUtils::alartCurnierFrictionResidual(pressure, augmented_pressure, radius);
122 const auto hsw =
123 ContactUtils::hueberStadlerWohlmuthFrictionResidual(pressure, augmented_pressure, radius);
124 for (const auto i : index_range(pressure))
125 EXPECT_NEAR(raw_value(hsw[i]), raw_value(weight * ac[i]), 1e-14);
126}
127
128TYPED_TEST(FrictionProjectionTest, DegreeTwoDegenerateState)
129{
130 using T = TypeParam;
131
132 const std::array<T, 2> pressure = {2.0, -3.0};
133 const std::array<T, 2> augmented_pressure = {0.0, 0.0};
134 const auto ac = ContactUtils::alartCurnierFrictionResidual(pressure, augmented_pressure, T(0.0));
135 const auto hsw =
136 ContactUtils::hueberStadlerWohlmuthFrictionResidual(pressure, augmented_pressure, T(0.0));
137
138 for (const auto i : index_range(pressure))
139 {
140 EXPECT_DOUBLE_EQ(raw_value(ac[i]), raw_value(pressure[i]));
141 EXPECT_DOUBLE_EQ(raw_value(hsw[i]), raw_value(pressure[i]));
142 }
143}
TYPED_TEST(FrictionProjectionTest, StickAndSlipRoots)
TYPED_TEST_SUITE(FrictionProjectionTest, FrictionProjectionTypes)
::testing::Types< Real, ADReal > FrictionProjectionTypes
const double T
auto norm(const T &value)
auto raw_value(const Eigen::Map< T > &in)
std::array< T, N > alartCurnierFrictionResidual(const std::array< T, N > &tangential_pressure, const std::array< T, N > &augmented_tangential_pressure, const T &radius)
Return the degree-one Alart-Curnier friction residual p_t - Proj_{B_radius}(q_t).
std::array< T, N > projectToClosedSphere(const std::array< T, N > &vector, const T &radius)
Project vector onto a closed sphere centered at the origin with radius radius.
T coulombFrictionRadius(const T &friction_coefficient, const T &augmented_normal_pressure)
Return the nonnegative Coulomb friction radius.
std::array< T, N > hueberStadlerWohlmuthFrictionResidual(const std::array< T, N > &tangential_pressure, const std::array< T, N > &augmented_tangential_pressure, const T &radius)
Return the degree-two Hueber-Stadler-Wohlmuth friction residual max(radius, ||q_t||) p_t - radius q_t...
T augmentedNormalPressure(const T &normal_pressure, const T &scaled_normal_gap)
Return the augmented normal pressure p_n - C_n g_bar.
const Real radius