UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
GaussSeidelCorotatedConstraints.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
6#include "ChaosStats.h"
12
13
14namespace Chaos::Softs
15{
16 template <typename T, typename ParticleType>
18 {
19
23 using Base::Measure;
24 using Base::DmInverse;
28 using Base::F;
29
30 public:
32 const ParticleType& InParticles,
34 const TArray<T>& EMeshArray,
41 const bool bDoQuasistaticsIn = false,
42 const bool bDoSORIn = true,
43 const T InOmegaSOR = (T)1.6,
45 const T& NuMesh = (T).3,
46 const bool bRecordMetricIn = false
47 )
50 {
53 for (int32 i = 0; i < IncidentElements.Num(); i++)
54 {
55 Particle2Incident[i] = i;
56 }
57 for (int32 e = 0; e < InMesh.Num(); e++)
58 {
59 for (int32 r = 0; r < 3; r++) {
60 for (int32 c = 0; c < 3; c++) {
61 DmInverse[(3 * 3) * e + 3 * r + c] /= Base::AlphaJArray[e];
62 }
63 }
64 }
65 if (!bDoQuasistatics)
66 {
68 }
69 if (bDoSOR)
70 {
73 }
76 }
77
79
80
81 void Apply(ParticleType& Particles, const T Dt) const
82 {
84 for (int32 i = 0; i < ParticlesPerColor.Num(); i++)
85 {
87 if (ParticlesPerColor[i].Num() % CorotatedParams.XPBDCorotatedBatchSize != 0)
88 {
89 NumBatch += 1;
90 }
91
92 PhysicsParallelFor(NumBatch, [&](const int32 BatchIndex)
93 {
95 int32 TaskIndex = CorotatedParams.XPBDCorotatedBatchSize * BatchIndex + BatchSubIndex;
96 if (TaskIndex < ParticlesPerColor[i].Num())
97 {
98 int32 ParticleIndex = ParticlesPerColor[i][TaskIndex];
99 Chaos::TVector<T, 3> Dx = ComputeDeltax(ParticleIndex, Particle2Incident[ParticleIndex - ParticleStartIndex], Particles,
100 Dt);
101 Particles.P(ParticleIndex) += Dx;
102 }
103 }
104 }, NumBatch < CorotatedParams.XPBDCorotatedBatchThreshold);
105
106 }
107 ApplySOR(Particles, Dt);
108 CurrentIt += 1;
109 }
110
111 void Init(const T Dt, const ParticleType& Particles) const
112 {
113 if (!bDoQuasistatics)
114 {
115 for (int32 i = 0; i < ParticleEndIndex - ParticleStartIndex; i++)
116 {
117 xtilde[i] = Particles.X(ParticleStartIndex + i) + Dt * Particles.V(ParticleStartIndex + i);
118 }
119 }
120 CurrentIt = 0;
121 }
122
123 void Init() const override {}
124
127 TArray<TVector<int32, 4>> GetMeshConstraints() const { return MeshConstraints; }
129
131 {
133 MeshArray.SetNum(MeshConstraints.Num());
134 for (int32 i = 0; i < MeshConstraints.Num(); i++)
135 {
136 MeshArray[i].SetNum(4);
137 for (int32 ie = 0; ie < 4; ie++)
138 {
139 MeshArray[i][ie] = MeshConstraints[i][ie];
140 }
141 }
142 return MeshArray;
143 }
144
145 // Apply Successive Over Relaxation (SOR) to accelerate convergence rate
146 void ApplySOR(ParticleType& Particles, const T Dt) const
147 {
148 if (bDoSOR)
149 {
151 {
152 int32 ParticleIndex = i + ParticleStartIndex;
153 if (Particles.InvM(ParticleIndex) != T(0) && CurrentIt > 3)
154 {
155 Particles.P(ParticleIndex) = OmegaSOR * (Particles.P(ParticleIndex) - X_k_1[i]) + X_k_1[i];
156 }
157 X_k_1[i] = X_k[i];
158 X_k[i] = Particles.P(ParticleIndex);
160 }
161 }
162
163 Chaos::TVector<T, 3> ComputePerParticleResidual(const int32 p, const int32 IncidentIndex, const ParticleType& Particles,
164 const T Dt, const bool AddMass = true) const
165 {
166
168 if (AddMass) {
169 for (int32 alpha = 0; alpha < 3; alpha++) {
170 res[alpha] = Particles.M(p) * (Particles.P(p)[alpha] - xtilde[p - ParticleStartIndex][alpha]);
171 }
172 }
173 for (int32 j = 0; j < IncidentElements[IncidentIndex].Num(); j++) {
177 Chaos::PMatrix<T, 3, 3> Fe = Base::F(e, Particles);
179
180 ComputeStress(Fe, MuElementArray[e], LambdaElementArray[e], P);
181
182 Chaos::PMatrix<T, 3, 3> force_term = -Measure[e] * DmInvT * P;
184 if (local_index > 0)
185 {
186 for (int32 c = 0; c < 3; c++)
187 {
188 dx[c] += force_term.GetAt(c, local_index - 1);
189 }
190 }
191 else
192 {
193 for (int32 c = 0; c < 3; c++)
194 {
195 for (int32 h = 0; h < 3; h++)
196 {
197 dx[c] -= force_term.GetAt(c, h);
198 }
199 }
200 }
201
202 for (int32 ll = 0; ll < 3; ll++) {
203 dx[ll] *= Dt * Dt;
204 }
205
206 for (int32 alpha = 0; alpha < 3; alpha++) {
207 res[alpha] -= dx[alpha];
208 }
209 }
210 return res;
211 }
212
213
215 const T Dt, const bool AddMass = true) const
216 {
218 if (AddMass) {
219 for (int32 alpha = 0; alpha < 3; alpha++) {
220 final_hessian.SetAt(alpha, alpha, Particles.M(p));
221 }
222 }
223
224 for (int32 j = 0; j < IncidentElements[IncidentIndex].Num(); j++) {
226 int32 ElementIndex = IncidentElements[IncidentIndex][j];
228 Chaos::PMatrix<T, 3, 3> Fe = Base::F(ElementIndex, Particles);
229
230 T Coeff = Dt * Dt * Measure[ElementIndex];
231
232 ComputeHessianHelper(Fe, DmInv, MuElementArray[ElementIndex], LambdaElementArray[ElementIndex], local_index, Coeff, final_hessian);
233
234 }
235 return final_hessian;
236 }
237
238
239 void AddHyperelasticResidualAndHessian (const ParticleType& Particles, const int32 ElementIndex, const int32 ElementIndexLocal, const T Dt, TVec3<T>& ParticleResidual, Chaos::PMatrix<T, 3, 3>& ParticleHessian)
240 {
241 Chaos::PMatrix<T, 3, 3> DmInvT = Base::ElementDmInv(ElementIndex).GetTransposed();
242 Chaos::PMatrix<T, 3, 3> Fe = F(ElementIndex, Particles);
244
245 this->ComputeStress(Fe, MuElementArray[ElementIndex], LambdaElementArray[ElementIndex], P);
246
247 Chaos::PMatrix<T, 3, 3> force_term = -Measure[ElementIndex] * DmInvT * P;
249 if (ElementIndexLocal > 0)
250 {
251 for (int32 c = 0; c < 3; c++)
252 {
253 dx[c] += force_term.GetAt(c, ElementIndexLocal - 1);
254 }
255 }
256 else
257 {
258 for (int32 c = 0; c < 3; c++)
259 {
260 for (int32 h = 0; h < 3; h++)
261 {
262 dx[c] -= force_term.GetAt(c, h);
263 }
264 }
265 }
266
267 for (int32 ll = 0; ll < 3; ll++) {
268 dx[ll] *= Dt * Dt;
269 }
270
271 for (int32 alpha = 0; alpha < 3; alpha++) {
272 ParticleResidual[alpha] -= dx[alpha];
273 }
274
275 ComputeHessianHelper(Fe, Base::ElementDmInv(ElementIndex), MuElementArray[ElementIndex], LambdaElementArray[ElementIndex], ElementIndexLocal, Dt * Dt * Measure[ElementIndex], ParticleHessian);
276
277 }
278
279 protected:
280 void InitColor(const ParticleType& Particles)
281 {
283 }
284
286 {
288 {
289 PCorotated(Fe, mu, lambda, P);
290 };
292 {
294 JFinvT.SetAt(0, 0, Fe.GetAt(1, 1) * Fe.GetAt(2, 2) - Fe.GetAt(2, 1) * Fe.GetAt(1, 2));
295 JFinvT.SetAt(0, 1, Fe.GetAt(2, 0) * Fe.GetAt(1, 2) - Fe.GetAt(1, 0) * Fe.GetAt(2, 2));
296 JFinvT.SetAt(0, 2, Fe.GetAt(1, 0) * Fe.GetAt(2, 1) - Fe.GetAt(2, 0) * Fe.GetAt(1, 1));
297 JFinvT.SetAt(1, 0, Fe.GetAt(2, 1) * Fe.GetAt(0, 2) - Fe.GetAt(0, 1) * Fe.GetAt(2, 2));
298 JFinvT.SetAt(1, 1, Fe.GetAt(0, 0) * Fe.GetAt(2, 2) - Fe.GetAt(2, 0) * Fe.GetAt(0, 2));
299 JFinvT.SetAt(1, 2, Fe.GetAt(2, 0) * Fe.GetAt(0, 1) - Fe.GetAt(0, 0) * Fe.GetAt(2, 1));
300 JFinvT.SetAt(2, 0, Fe.GetAt(0, 1) * Fe.GetAt(1, 2) - Fe.GetAt(1, 1) * Fe.GetAt(0, 2));
301 JFinvT.SetAt(2, 1, Fe.GetAt(1, 0) * Fe.GetAt(0, 2) - Fe.GetAt(0, 0) * Fe.GetAt(1, 2));
302 JFinvT.SetAt(2, 2, Fe.GetAt(0, 0) * Fe.GetAt(1, 1) - Fe.GetAt(1, 0) * Fe.GetAt(0, 1));
303
304 Chaos::PMatrix<T, 3, 3> JFinv = JFinvT.GetTransposed();
305
306 if (local_index == 0) {
307 T DmInvsum = T(0);
308 for (int32 nu = 0; nu < 3; nu++) {
309 T localDmsum = T(0);
310 for (int32 k = 0; k < 3; k++) {
311 localDmsum += DmInv.GetAt(k, nu);
312 }
314 }
315 for (int32 alpha = 0; alpha < 3; alpha++) {
316 final_hessian.SetAt(alpha, alpha, final_hessian.GetAt(alpha, alpha) + Coeff * T(2) * mu * DmInvsum);
317 }
318
320 Chaos::TVector<T, 3> l((T)0.);
321 for (int32 alpha = 0; alpha < 3; alpha++) {
322 for (int32 k = 0; k < 3; k++) {
323 l[alpha] += DmInvJFinv.GetAt(k, alpha);
324 }
325 }
326 for (int32 alpha = 0; alpha < 3; alpha++)
327 {
328 final_hessian.SetRow(alpha, final_hessian.GetRow(alpha) + Coeff * lambda * l[alpha] * l);
329 }
330
331 }
332 else {
333 T DmInvsum = T(0);
334 for (int32 nu = 0; nu < 3; nu++)
335 {
336 DmInvsum += DmInv.GetAt(local_index - 1, nu) * DmInv.GetAt(local_index - 1, nu);
337 }
338 for (int32 alpha = 0; alpha < 3; alpha++)
339 {
340 final_hessian.SetAt(alpha, alpha, final_hessian.GetAt(alpha, alpha) + Coeff * T(2) * mu * DmInvsum);
341 }
342
344 Chaos::TVector<T, 3> l((T)0.);
345 for (int32 alpha = 0; alpha < 3; alpha++) {
346 l[alpha] = DmInvJFinv.GetAt(local_index - 1, alpha);
347 }
348 for (int32 alpha = 0; alpha < 3; alpha++)
349 {
350 final_hessian.SetRow(alpha, final_hessian.GetRow(alpha) + Coeff * lambda * l[alpha] * l);
351 }
352 }
353 };
354
355 AddAdditionalRes = [](const ParticleType& InParticles, const int32 p, const T Dt, TVec3<T>& res) {};
356 AddAdditionalHessian = [](const ParticleType& InParticles, const int32 p, const T Dt, Chaos::PMatrix<T, 3, 3>& hessian) {};
357 }
358
359 private:
360
361 TVector<T, 3> ComputeDeltax(const int32 p, const int32 IncidentIndex, const ParticleType& Particles,
362 const T Dt) const
363 {
365
366 AddAdditionalRes(Particles, p, Dt, ParticleResidual);
367
368 if (ParticleResidual.Size() > LocalNewtonTol)
369 {
371 AddAdditionalHessian(Particles, p, Dt, SimplifiedHessian);
372
373 T HessianDet = SimplifiedHessian.Determinant();
375 {
376 Chaos::PMatrix<T, 3, 3> HessianInv = SimplifiedHessian.SymmetricCofactorMatrix();
377 HessianInv *= T(1) / HessianDet;
378 return HessianInv.GetTransposed() * (-ParticleResidual);
379 }
380 }
381 return TVector<T, 3>((T)0.);
382 }
383
384
385
386 protected:
387
391 T LocalNewtonTol = T(1e-5);
398 bool bDoQuasistatics = false;
399 bool bDoSOR = true;
400 //Parameter to control the behavior of SOR. 1-1.7 is the usual range. Larger paramater leads to potentially more convergence but less stable behavior.
401 T OmegaSOR = T(1.6);
402 mutable int32 CurrentIt = 0;
405
406 public:
407 TFunction<void(const ParticleType&, const int32, const T, TVec3<T>&)> AddAdditionalRes;
408 TFunction<void(const ParticleType&, const int32, const T, Chaos::PMatrix<T, 3, 3>&)> AddAdditionalHessian;
410 };
411
412
413}// End namespace Chaos::Softs
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
@ INDEX_NONE
Definition CoreMiscDefines.h:150
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 TRACE_CPUPROFILER_EVENT_SCOPE(Name)
Definition CpuProfilerTrace.h:528
@ Num
Definition MetalRHIPrivate.h:234
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
Definition Matrix.h:21
Definition GaussSeidelCorotatedConstraints.h:18
TArray< int32 > Particle2Incident
Definition GaussSeidelCorotatedConstraints.h:388
virtual ~FGaussSeidelCorotatedConstraints()
Definition GaussSeidelCorotatedConstraints.h:78
void Init(const T Dt, const ParticleType &Particles) const
Definition GaussSeidelCorotatedConstraints.h:111
TUniquePtr< TArray< int32 > > ParticleColors
Definition GaussSeidelCorotatedConstraints.h:409
Chaos::PMatrix< T, 3, 3 > ComputePerParticleCorotatedHessianSimple(const int32 p, const int32 IncidentIndex, const ParticleType &Particles, const T Dt, const bool AddMass=true) const
Definition GaussSeidelCorotatedConstraints.h:214
void SetParticlesPerColor(TArray< TArray< int32 > > &&InParticlesPerColor)
Definition GaussSeidelCorotatedConstraints.h:128
FGaussSeidelCorotatedConstraints(const ParticleType &InParticles, const TArray< TVector< int32, 4 > > &InMesh, const TArray< T > &EMeshArray, const TArray< T > &NuMeshArray, TArray< T > &&AlphaJMeshArray, TArray< TArray< int32 > > &&IncidentElementsIn, TArray< TArray< int32 > > &&IncidentElementsLocalIn, const int32 ParticleStartIndexIn, const int32 ParticleEndIndexIn, const bool bDoQuasistaticsIn=false, const bool bDoSORIn=true, const T InOmegaSOR=(T) 1.6, const FDeformableXPBDCorotatedParams &InParams=FDeformableXPBDCorotatedParams(), const T &NuMesh=(T).3, const bool bRecordMetricIn=false)
Definition GaussSeidelCorotatedConstraints.h:31
TArray< Chaos::TVector< T, 3 > > X_k
Definition GaussSeidelCorotatedConstraints.h:397
bool bDoSOR
Definition GaussSeidelCorotatedConstraints.h:399
int32 ParticleStartIndex
Definition GaussSeidelCorotatedConstraints.h:393
TFunction< void(const Chaos::PMatrix< T, 3, 3 > &, const Chaos::PMatrix< T, 3, 3 > &, const T, const T, const int32, const T, Chaos::PMatrix< T, 3, 3 > &)> ComputeHessianHelper
Definition GaussSeidelCorotatedConstraints.h:404
TFunction< void(const Chaos::PMatrix< T, 3, 3 > &, const T, const T, Chaos::PMatrix< T, 3, 3 > &)> ComputeStress
Definition GaussSeidelCorotatedConstraints.h:403
void InitializeCorotatedLambdas()
Definition GaussSeidelCorotatedConstraints.h:285
T LocalNewtonTol
Definition GaussSeidelCorotatedConstraints.h:391
int32 CurrentIt
Definition GaussSeidelCorotatedConstraints.h:402
void InitColor(const ParticleType &Particles)
Definition GaussSeidelCorotatedConstraints.h:280
TFunction< void(const ParticleType &, const int32, const T, TVec3< T > &)> AddAdditionalRes
Definition GaussSeidelCorotatedConstraints.h:407
void Init() const override
Definition GaussSeidelCorotatedConstraints.h:123
void ApplySOR(ParticleType &Particles, const T Dt) const
Definition GaussSeidelCorotatedConstraints.h:146
TArray< TArray< int32 > > GetMeshArray() const
Definition GaussSeidelCorotatedConstraints.h:130
TArray< TArray< int32 > > IncidentElements
Definition GaussSeidelCorotatedConstraints.h:389
TArray< TVector< int32, 4 > > GetMeshConstraints() const
Definition GaussSeidelCorotatedConstraints.h:127
TArray< TArray< int32 > > ParticlesPerColor
Definition GaussSeidelCorotatedConstraints.h:392
T OmegaSOR
Definition GaussSeidelCorotatedConstraints.h:401
bool bDoQuasistatics
Definition GaussSeidelCorotatedConstraints.h:398
TArray< Chaos::TVector< T, 3 > > xtilde
Definition GaussSeidelCorotatedConstraints.h:395
TFunction< void(const ParticleType &, const int32, const T, Chaos::PMatrix< T, 3, 3 > &)> AddAdditionalHessian
Definition GaussSeidelCorotatedConstraints.h:408
int32 ParticleEndIndex
Definition GaussSeidelCorotatedConstraints.h:394
void Apply(ParticleType &Particles, const T Dt) const
Definition GaussSeidelCorotatedConstraints.h:81
TArray< TArray< int32 > > IncidentElementsLocal
Definition GaussSeidelCorotatedConstraints.h:390
TArray< TArray< int32 > > & GetIncidentElements()
Definition GaussSeidelCorotatedConstraints.h:125
TArray< TArray< int32 > > & GetIncidentElementsLocal()
Definition GaussSeidelCorotatedConstraints.h:126
TArray< Chaos::TVector< T, 3 > > X_k_1
Definition GaussSeidelCorotatedConstraints.h:396
void AddHyperelasticResidualAndHessian(const ParticleType &Particles, const int32 ElementIndex, const int32 ElementIndexLocal, const T Dt, TVec3< T > &ParticleResidual, Chaos::PMatrix< T, 3, 3 > &ParticleHessian)
Definition GaussSeidelCorotatedConstraints.h:239
Chaos::TVector< T, 3 > ComputePerParticleResidual(const int32 p, const int32 IncidentIndex, const ParticleType &Particles, const T Dt, const bool AddMass=true) const
Definition GaussSeidelCorotatedConstraints.h:163
Definition XPBDCorotatedConstraints.h:20
TArray< T > LambdaArray
Definition XPBDCorotatedConstraints.h:637
TArray< TVector< int32, 4 > > MeshConstraints
Definition XPBDCorotatedConstraints.h:654
TArray< T > Measure
Definition XPBDCorotatedConstraints.h:655
TArray< T > AlphaJArray
Definition XPBDCorotatedConstraints.h:648
FDeformableXPBDCorotatedParams CorotatedParams
Definition XPBDCorotatedConstraints.h:641
TArray< T > DmInverse
Definition XPBDCorotatedConstraints.h:638
PMatrix< T, 3, 3 > F(const int e, const ParticleType &InParticles) const
Definition XPBDCorotatedConstraints.h:230
TArray< T > MuElementArray
Definition XPBDCorotatedConstraints.h:646
PMatrix< T, 3, 3 > ElementDmInv(const int e) const
Definition XPBDCorotatedConstraints.h:234
TArray< T > LambdaElementArray
Definition XPBDCorotatedConstraints.h:647
Definition Vector.h:1000
Definition Vector.h:41
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
void Init(const ElementType &Element, SizeType Number)
Definition Array.h:3043
Definition AndroidPlatformMisc.h:14
Definition UniquePtr.h:107
Definition CollectionEmbeddedSpringConstraintFacade.cpp:6
void PCorotated(const Chaos::PMatrix< T, 3, 3 > &Fe, const T mu, const T lambda, Chaos::PMatrix< T, 3, 3 > &P)
Definition NewtonCorotatedCache.cpp:116
CHAOS_API TArray< TArray< int32 > > ComputeNodalColoring(const TArray< TVec4< int32 > > &Graph, const Chaos::TDynamicParticles< T, 3 > &InParticles, const int32 GraphParticlesStart, const int32 GraphParticlesEnd, const TArray< TArray< int32 > > &IncidentElements, const TArray< TArray< int32 > > &IncidentElementsLocalIndex)
void CHAOS_API PhysicsParallelFor(int32 InNum, TFunctionRef< void(int32)> InCallable, bool bForceSingleThreaded=false)
Definition Parallel.cpp:55
@ false
Definition radaudio_common.h:23
Definition ChaosDeformableSolverTypes.h:219
int32 XPBDCorotatedBatchSize
Definition ChaosDeformableSolverTypes.h:220
int32 XPBDCorotatedBatchThreshold
Definition ChaosDeformableSolverTypes.h:221