UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
GaussSeidelLinearCodimensionalConstraints.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
5#include "ChaosStats.h"
10#include "Chaos/Vector.h"
11
12
13namespace Chaos::Softs
14{
15 template <typename T, typename ParticleType>
17 {
18
19 public:
21 const ParticleType& InParticles,
23 const T& EMesh = (T)10.0,
24 const T& NuMesh = (T).3
25 )
27 {
28 Measure.Init((T)0., MeshConstraints.Num());
29 Lambda = EMesh * NuMesh / (((T)1. + NuMesh) * ((T)1. - (T)2. * NuMesh));
30 Mu = EMesh / ((T)2. * ((T)1. + NuMesh));
31
34
36 }
37
39 const ParticleType& InParticles,
41 const TArray<T>& EMeshArray,
42 const T& NuMesh = (T).3
43 )
45 {
46 Measure.Init((T)0., MeshConstraints.Num());
47
51
52 for (int32 e = 0; e < InMesh.Num(); e++)
53 {
54 LambdaElementArray[e] = EMeshArray[e] * NuMesh / (((T)1. + NuMesh) * ((T)1. - (T)2. * NuMesh));
55 MuElementArray[e] = EMeshArray[e] / ((T)2. * ((T)1. + NuMesh));
56 }
57 }
58
60
61 PMatrix<T, 3, 3> DsInit(const int32 E, const ParticleType& InParticles)
62 {
63 PMatrix<T, 3, 3> Result((T)0.);
64 for (int32 i = 0; i < 3; i++)
65 {
66 for (int32 c = 0; c < 3; c++)
67 {
68 Result.SetAt(c, i, InParticles.X(MeshConstraints[E][i + 1])[c] - InParticles.X(MeshConstraints[E][0])[c]);
69 }
70 }
71 return Result;
72 }
73
74 PMatrix<T, 3, 2> Ds(const int32 E, const ParticleType& InParticles) const
75 {
76 if (INDEX_NONE < E && E< MeshConstraints.Num()
80 {
83
84 return PMatrix<T, 3, 2>(
85 P1P0[0], P1P0[1], P1P0[2],
86 P2P0[0], P2P0[1], P2P0[2]);
87 }
88 else
89 {
90 return PMatrix<T, 3, 2>(
91 (T)0., (T)0, (T)0,
92 (T)0, (T)0, (T)0);
93 }
94 }
95
96 PMatrix<T, 3, 2> F(const int32 E, const ParticleType& InParticles) const
97 {
98 if (INDEX_NONE < E && E < DmInverse.Num())
99 {
100 return Ds(E, InParticles) * DmInverse[E];
101 }
102 else
103 {
104 return PMatrix<T, 3, 2>(
105 (T)0., (T)0, (T)0,
106 (T)0, (T)0, (T)0);
107 }
108 }
109
111 {
113 Constraints.SetNum(MeshConstraints.Num());
114 for (int32 i = 0; i < MeshConstraints.Num(); i++)
115 {
116 Constraints[i].SetNum(3);
117 for (int32 j = 0; j < 3; j++)
118 {
119 Constraints[i][j] = MeshConstraints[i][j];
120 }
121 }
122 return Constraints;
123 }
124
125 protected:
126
127 void InitializeCodimensionData(const ParticleType& Particles)
128 {
129 Measure.Init((T)0., MeshConstraints.Num());
130 DmInverse.Init(PMatrix<FSolverReal, 2, 2>(0.f, 0.f, 0.f), MeshConstraints.Num());
131 for (int32 e = 0; e < MeshConstraints.Num(); e++)
132 {
133 check(MeshConstraints[e][0] < (int32)Particles.Size() && MeshConstraints[e][0] > INDEX_NONE);
134 check(MeshConstraints[e][1] < (int32)Particles.Size() && MeshConstraints[e][1] > INDEX_NONE);
135 check(MeshConstraints[e][2] < (int32)Particles.Size() && MeshConstraints[e][2] > INDEX_NONE);
136 if (MeshConstraints[e][0] < (int32)Particles.Size() && MeshConstraints[e][0] > INDEX_NONE
137 && MeshConstraints[e][1] < (int32)Particles.Size() && MeshConstraints[e][1] > INDEX_NONE
138 && MeshConstraints[e][2] < (int32)Particles.Size() && MeshConstraints[e][2] > INDEX_NONE)
139 {
140 const TVec3<T> X1X0 = Particles.GetX(MeshConstraints[e][1]) - Particles.GetX(MeshConstraints[e][0]);
141 const TVec3<T> X2X0 = Particles.GetX(MeshConstraints[e][2]) - Particles.GetX(MeshConstraints[e][0]);
142 PMatrix<T, 2, 2> Dm((T)0., (T)0., (T)0.);
143 Dm.M[0] = X1X0.Size();
144 Dm.M[2] = X1X0.Dot(X2X0) / Dm.M[0];
145 Dm.M[3] = Chaos::TVector<T, 3>::CrossProduct(X1X0, X2X0).Size() / Dm.M[0];
147 ensureMsgf(Measure[e] > (T)0., TEXT("Degenerate triangle detected"));
148
149 PMatrix<T, 2, 2> DmInv = Dm.Inverse();
150 DmInverse[e] = DmInv;
151 }
152 }
153 }
154
155 static T SafeRecip(const T Len, const T Fallback)
156 {
157 if (Len > (T)UE_SMALL_NUMBER)
158 {
159 return (T)1. / Len;
160 }
161 return Fallback;
162 }
163
164 public:
165 void AddHyperelasticResidualAndHessian(const ParticleType& Particles, const int32 ElementIndex, const int32 ElementIndexLocal, const T Dt, TVec3<T>& ParticleResidual, Chaos::PMatrix<T, 3, 3>& ParticleHessian)
166 {
167 check(ElementIndex < DmInverse.Num() && ElementIndex > INDEX_NONE);
168 check(ElementIndex < MuElementArray.Num());
169 check(ElementIndex < Measure.Num());
170 check(ElementIndex < LambdaElementArray.Num());
172 if (ElementIndexLocal < 3
174 && ElementIndex < Measure.Num()
175 && ElementIndex < MuElementArray.Num()
176 && ElementIndex < LambdaElementArray.Num()
177 && ElementIndex < DmInverse.Num()
178 && ElementIndex > INDEX_NONE)
179 {
180 const Chaos::PMatrix<T, 2, 2> DmInvT = DmInverse[ElementIndex].GetTransposed(), DmInv = DmInverse[ElementIndex];
181 const Chaos::PMatrix<T, 3, 2> Fe = F(ElementIndex, Particles);
182
183 PMatrix<T, 3, 2> Pe(TVec3<T>((T)0.), TVec3<T>((T)0.)), ForceTerm(TVec3<T>((T)0.), TVec3<T>((T)0.));
184 Pe = T(2) * MuElementArray[ElementIndex] * Fe;
185
186 ForceTerm = -Measure[ElementIndex] * Pe * DmInverse[ElementIndex].GetTransposed();
187
188 Chaos::TVector<T, 3> Dx((T)0.);
189 if (ElementIndexLocal > 0)
190 {
191 for (int32 c = 0; c < 3; c++)
192 {
193 Dx[c] += ForceTerm.M[ElementIndexLocal * 3 - 3 + c];
194 }
195 }
196 else
197 {
198 for (int32 c = 0; c < 3; c++)
199 {
200 for (int32 h = 0; h < 2; h++)
201 {
202 Dx[c] -= ForceTerm.M[h * 3 + c];
203 }
204 }
205 }
206
207 Dx *= Dt * Dt;
208 ParticleResidual -= Dx;
209 T Coeff = Dt * Dt * Measure[ElementIndex];
210
211 if (ElementIndexLocal == 0)
212 {
213 T DmInvsum = T(0);
214 for (int32 nu = 0; nu < 2; nu++)
215 {
216 T localDmsum = T(0);
217 for (int32 k = 0; k < 2; k++)
218 {
219 localDmsum += DmInv.M[nu * 2 + k];
220 }
222 }
223 for (int32 alpha = 0; alpha < 3; alpha++)
224 {
225 ParticleHessian.SetAt(alpha, alpha, ParticleHessian.GetAt(alpha, alpha) + Coeff * T(2) * MuElementArray[ElementIndex] * DmInvsum);
226 }
227 }
228 else
229 {
230 T DmInvsum = T(0);
231 for (int32 nu = 0; nu < 2; nu++)
232 {
233 DmInvsum += DmInv.GetAt(ElementIndexLocal - 1, nu) * DmInv.GetAt(ElementIndexLocal - 1, nu);
234 }
235 for (int32 alpha = 0; alpha < 3; alpha++)
236 {
237 ParticleHessian.SetAt(alpha, alpha, ParticleHessian.GetAt(alpha, alpha) + Dt * Dt * Measure[ElementIndex] * T(2) * MuElementArray[ElementIndex] * DmInvsum);
238 }
239 }
240 }
241 }
242
243 protected:
245
246 //material constants calculated from E:
247 T Mu;
252
255 };
256
257} // End namespace Chaos::Softs
258
259
#define check(expr)
Definition AssertionMacros.h:314
#define ensureMsgf( InExpression, InFormat,...)
Definition AssertionMacros.h:465
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
Definition Matrix.h:21
Definition GaussSeidelLinearCodimensionalConstraints.h:17
T Lambda
Definition GaussSeidelLinearCodimensionalConstraints.h:248
void InitializeCodimensionData(const ParticleType &Particles)
Definition GaussSeidelLinearCodimensionalConstraints.h:127
PMatrix< T, 3, 2 > F(const int32 E, const ParticleType &InParticles) const
Definition GaussSeidelLinearCodimensionalConstraints.h:96
TArray< T > Measure
Definition GaussSeidelLinearCodimensionalConstraints.h:254
PMatrix< T, 3, 3 > DsInit(const int32 E, const ParticleType &InParticles)
Definition GaussSeidelLinearCodimensionalConstraints.h:61
static T SafeRecip(const T Len, const T Fallback)
Definition GaussSeidelLinearCodimensionalConstraints.h:155
FGaussSeidelLinearCodimensionalConstraints(const ParticleType &InParticles, const TArray< TVector< int32, 3 > > &InMesh, const T &EMesh=(T) 10.0, const T &NuMesh=(T).3)
Definition GaussSeidelLinearCodimensionalConstraints.h:20
T Mu
Definition GaussSeidelLinearCodimensionalConstraints.h:247
TArray< T > AlphaJArray
Definition GaussSeidelLinearCodimensionalConstraints.h:251
void AddHyperelasticResidualAndHessian(const ParticleType &Particles, const int32 ElementIndex, const int32 ElementIndexLocal, const T Dt, TVec3< T > &ParticleResidual, Chaos::PMatrix< T, 3, 3 > &ParticleHessian)
Definition GaussSeidelLinearCodimensionalConstraints.h:165
virtual ~FGaussSeidelLinearCodimensionalConstraints()
Definition GaussSeidelLinearCodimensionalConstraints.h:59
FGaussSeidelLinearCodimensionalConstraints(const ParticleType &InParticles, const TArray< TVector< int32, 3 > > &InMesh, const TArray< T > &EMeshArray, const T &NuMesh=(T).3)
Definition GaussSeidelLinearCodimensionalConstraints.h:38
PMatrix< T, 3, 2 > Ds(const int32 E, const ParticleType &InParticles) const
Definition GaussSeidelLinearCodimensionalConstraints.h:74
TArray< TVector< int32, 3 > > MeshConstraints
Definition GaussSeidelLinearCodimensionalConstraints.h:253
TArray< T > LambdaElementArray
Definition GaussSeidelLinearCodimensionalConstraints.h:250
TArray< T > MuElementArray
Definition GaussSeidelLinearCodimensionalConstraints.h:249
TArray< FSolverMatrix22 > DmInverse
Definition GaussSeidelLinearCodimensionalConstraints.h:244
TArray< TArray< int32 > > GetConstraintsArray() const
Definition GaussSeidelLinearCodimensionalConstraints.h:110
Definition Vector.h:1000
Definition Vector.h:41
Definition Constraints.Build.cs:6
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void Init(const ElementType &Element, SizeType Number)
Definition Array.h:3043
Definition CollectionEmbeddedSpringConstraintFacade.cpp:6