UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Poisson.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4//#include "ChaosFlesh/FleshCollectionUtility.h"
6#include "Chaos/Math/Krylov.h"
7#include "Chaos/UniformGrid.h"
8#include "Chaos/Vector.h"
9#include "Math/Matrix.h"
10#include "Math/Vector.h"
11#include "Chaos/Utilities.h"
12#include <iostream>
13
14namespace Chaos {
15
16// Set/Get i, j
17
18template <class T>
19inline void RowMaj3x3Set(T* A, const int32 i, const int32 j, const T Value)
20{
21 A[3 * i + j] = Value;
22}
23
24template <class T>
25inline const T& RowMaj3x3Get(const T* A, const int32 i, const int32 j)
26{
27 return A[3 * i + j];
28}
29
30template <class T>
31inline T& RowMaj3x3Get(T* A, const int32 i, const int32 j)
32{
33 return A[3 * i + j];
34}
35
36// Set/Get row
37
38template <class T>
39inline void RowMaj3x3SetRow(T* A, const int32 i, const T* Values)
40{
41 for (int32 j = 0; j < 3; j++)
42 {
43 RowMaj3x3Set(A, i, j, Values[i]);
44 }
45}
46
47template <class T, class TV>
48inline void RowMaj3x3SetRow(T* A, const int32 i, const TV Value)
49{
50 const T Tmp[3]{ static_cast<T>(Value[0]), static_cast<T>(Value[1]), static_cast<T>(Value[2]) };
51 RowMaj3x3SetRow(A, i, &Tmp[0]);
52}
53
54template <class T, class TV>
55inline void RowMaj3x3GetRow(T* A, const int32 i, TV& Row)
56{
57 for (int j = 0; j < 3; j++)
58 {
59 Row[j] = RowMaj3x3Get(A, i, j);
60 }
61}
62
63// Set/Get col
64
65template <class T>
66inline void RowMaj3x3SetCol(T* A, const int32 j, const T* Values)
67{
68 for (int32 i = 0; i < 3; i++)
69 {
70 RowMaj3x3Set(A, i, j, Values[i]);
71 }
72}
73
74template <class T, class TV>
75inline void RowMaj3x3SetCol(T* A, const int32 j, const TV Value)
76{
77 for (int32 i = 0; i < 3; i++)
78 {
79 RowMaj3x3Set(A, i, j, static_cast<T>(Value[i]));
80 }
81}
82
83template <class T, class TV>
84inline void RowMaj3x3GetCol(T* A, const int32 j, TV& Col)
85{
86 for (int i = 0; i < 3; i++)
87 {
88 Col[i] = RowMaj3x3Get(A, i, j);
89 }
90}
91
92// Determinant
93
94template <class T>
95inline T RowMaj3x3Determinant(const T A0, const T A1, const T A2, const T A3, const T A4, const T A5, const T A6, const T A7, const T A8)
96{
97 return A0 * (A4 * A8 - A5 * A7) - A1 * (A3 * A8 - A5 * A6) + A2 * (A3 * A7 - A4 * A6);
98}
99
100template <class T>
101inline T RowMaj3x3Determinant(const T* A)
102{
103 return RowMaj3x3Determinant(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[8]);
104}
105
106// Inverse
107
108template <class T>
109inline void RowMaj3x3Inverse(const T Det, const T A0, const T A1, const T A2, const T A3, const T A4, const T A5, const T A6, const T A7, const T A8, T* Inv)
110{
111 if (Det == T(0))
112 {
113 for (int i = 0; i < 9; i++)
114 Inv[i] = T(0);
115 Inv[0] = T(1);
116 Inv[4] = T(1);
117 Inv[8] = T(1);
118 return;
119 }
120
121 Inv[0] = (A4 * A8 - A5 * A7) / Det;
122 Inv[1] = (A2 * A7 - A1 * A8) / Det;
123 Inv[2] = (A1 * A5 - A2 * A4) / Det;
124 Inv[3] = (A5 * A6 - A3 * A8) / Det;
125 Inv[4] = (A0 * A8 - A2 * A6) / Det;
126 Inv[5] = (A2 * A3 - A0 * A5) / Det;
127 Inv[6] = (A3 * A7 - A4 * A6) / Det;
128 Inv[7] = (A1 * A6 - A0 * A7) / Det;
129 Inv[8] = (A0 * A4 - A1 * A3) / Det;
130}
131
132template <class T>
133inline void RowMaj3x3Inverse(const T Det, const T* A, T* Inv)
134{
135 RowMaj3x3Inverse(Det, A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[8], Inv);
136}
137
138template <class T>
139inline void RowMaj3x3Inverse(const T* A, T* Inv)
140{
142}
143
144// Transpose
145
146template <class T>
147inline void RowMaj3x3Transpose(const T* A, T* Transpose)
148{
149 for (int32 i = 0; i < 3; i++)
150 {
151 for (int32 j = 0; j < 3; j++)
152 {
153 Transpose[3 * j + i] = A[3 * i + j];
154 }
155 }
156}
157
158template <class T,class TV>
159inline TV RowMaj3x3Multiply(const T* A, const TV& x)
160{
161 TV Result(0,0,0);
162 for (int32 i = 0; i < 3; i++)
163 {
164 for (int32 j = 0; j < 3; j++)
165 {
166 Result[i] += A[3 * i + j] * x[j];
167 }
168 }
169 return Result;
170}
171
172template <class T, class TV>
173inline TV RowMaj3x3RobustSolveLinearSystem(const T* A, const TV& b)
174{
175 T Cofactor11 = A[4] * A[8] - A[7] * A[5];
176 T Cofactor12 = A[7] * A[2] - A[1] * A[8];
177 T Cofactor13 = A[1] * A[5] - A[4] * A[2];
178 T Determinant = A[0] * Cofactor11 + A[3] * Cofactor12 + A[6] * Cofactor13;
179
180 T Matrix[9] =
182 A[6] * A[5] - A[3] * A[8], A[0] * A[8] - A[6] * A[2], A[3] * A[2] - A[0] * A[5],
183 A[3] * A[7] - A[6] * A[4], A[6] * A[1] - A[0] * A[7], A[0] * A[4] - A[3] * A[1] };
185
186 T RelativeTolerance = static_cast<T>(TNumericLimits<float>::Min()) * FMath::Max3(FMath::Abs(UnscaledResult[0]), FMath::Abs(UnscaledResult[1]), FMath::Abs(UnscaledResult[2]));
187 if (FMath::Abs(Determinant) <= RelativeTolerance)
188 {
189 RelativeTolerance = FMath::Max(RelativeTolerance, static_cast<T>(TNumericLimits<float>::Min()));
190 Determinant = Determinant >= 0 ? RelativeTolerance : -RelativeTolerance;
191 }
192 return UnscaledResult / Determinant;
193}
194
195template <class T, class TV=FVector3f, class TV_INT=FIntVector4, int32 d=3>
196void
198 const TArray<TV_INT>& Mesh,
199 const TArray<TV>& X,
202{
203 De_inverse.SetNumUninitialized(d * d * Mesh.Num());
204 measure.SetNumUninitialized(Mesh.Num());
205
206 const int32* MeshPtr = &Mesh[0][0]; // Assumes Mesh is a continuguous array of int32.
207
208 //PhysicsParallelForRange(Mesh.Num(), [&](const int32 eBegin, const int32 eEnd)
209 const int32 eBegin = 0; const int32 eEnd = Mesh.Num();
210 {
211 T Inv[d*d];
212 for(int32 e=eBegin; e < eEnd; e++)
213 {
214 const TV_INT& Elem = Mesh[e];
215 T De[9] =
216 {
217 X[Elem[1]][0] - X[Elem[0]][0], X[Elem[2]][0] - X[Elem[0]][0], X[Elem[3]][0] - X[Elem[0]][0],
218 X[Elem[1]][1] - X[Elem[0]][1], X[Elem[2]][1] - X[Elem[0]][1], X[Elem[3]][1] - X[Elem[0]][1],
219 X[Elem[1]][2] - X[Elem[0]][2], X[Elem[2]][2] - X[Elem[0]][2], X[Elem[3]][2] - X[Elem[0]][2]
220 };
221
223 measure[e] = Det / (T)6;
224
226
227 for (int32 i = 0; i < d*d; i++)
228 {
229 De_inverse[d*d*e+i] = Inv[i];
230 }
231 }
232 }
233 //},
234 //100,
235 //Mesh.Num() < 100);
236}
237
238template <class T>
239void Fill(TArray<T>& Array, const T Value)
240{
241 for (int32 Idx = 0; Idx < Array.Num(); ++Idx)
242 Array[Idx] = Value;
243}
244
246{
247 int32 MinIdx = 0;
248 for (int32 i = 1; i < ElemIdx.Num(); i++)
249 {
250 if (ElemIdx[i] < ElemIdx[MinIdx])
251 MinIdx = i;
252 }
253 return (ElemIdx[MinIdx] * 4) + LocalIdx[MinIdx];
254}
255
256template <class T, class TV, class TV_INT = FIntVector4, int d = 3>
259 const TArray<TV_INT>& Mesh,
260 const TArray<TV>& X,
261 const int32 MaxItCG,
262 const T CGTol,
263 TArray<T>& Weights)
264{
268
270 TArray<TArray<int32>> IncidentElements = Chaos::Utilities::ComputeIncidentElements<4>(Mesh, &IncidentElementsLocalIndex);
271
272 auto ProjectBCs = [&InConstrainedNodes] (TArray<T>& U)
273 {
274 for (int32 i = 0; i < InConstrainedNodes.Num(); i++)
275 {
276 U[InConstrainedNodes[i]] = (T)0.;
277 }
278 };
279
280 auto MultiplyLaplacian = [&](TArray<T>& LU, const TArray<T>& U)
281 {
282 Laplacian(
283 Mesh,
284 IncidentElements,
287 measure,
288 U,
289 LU);
290 ProjectBCs(LU);
291 };
292
293 Fill(Weights, T(0));
294
296 InitialGuess.Init((T)0., Weights.Num());
297 for (int32 i = 0; i < InConstrainedNodes.Num(); i++)
298 {
300 }
302 MinusResidual.Init((T)0., Weights.Num());
304
306 MinusDw.Init((T)0., Weights.Num());
308
309 for (int32 i = 0; i < InitialGuess.Num(); i++)
310 {
311 Weights[i] = InitialGuess[i] - MinusDw[i];
312 }
313
314}
315
316template <class T, class TV_INT=FIntVector4, int d=3>
317void
319 const TArray<TV_INT>& Mesh,
320 const TArray<TArray<int32>>& IncidentElements,
322 const TArray<T>& De_inverse,
323 const TArray<T>& measure,
324 const TArray<T>& u,
325 TArray<T>& Lu)
326{
328 grad_Nie_hat[0] = { T(-1),T(-1),T(-1) };
329 grad_Nie_hat[1] = { T(1),T(0),T(0) };
330 grad_Nie_hat[2] = { T(0),T(1),T(0) };
331 grad_Nie_hat[3] = { T(0),T(0),T(1) };
332
333 Lu.SetNum(u.Num());
334 Fill(Lu, T(0));
335
336 //first compute element contributions
338 const int32* MeshPtr = &Mesh[0][0]; // Assumes Mesh is a contiguous array of int32.
339 PhysicsParallelFor(Mesh.Num(), [&](const int32 e)
340 {
341 T Deinv[d * d]{
342 De_inverse[d * d * e + 0],
343 De_inverse[d * d * e + 1],
344 De_inverse[d * d * e + 2],
345 De_inverse[d * d * e + 3],
346 De_inverse[d * d * e + 4],
347 De_inverse[d * d * e + 5],
348 De_inverse[d * d * e + 6],
349 De_inverse[d * d * e + 7],
350 De_inverse[d * d * e + 8],
351 };
352 T De_inverse_transpose[d * d];
354
355 const TV_INT& Elem = Mesh[e];
356
358 for (int32 ie = 0; ie < d+1; ie++)
359 {
361 for (int32 je = 0; je < d+1; je++)
362 {
365 element_contributions[(d + 1) * e + ie] += Ae_ieje * u[Elem[je]];
366 }
367 }
368 });
369
370 //now gather from elements
371 PhysicsParallelFor(IncidentElements.Num(), [&](const int32 i)
372 {
373 if (!IncidentElements[i].Num())
374 {
375 return;
376 }
377 const TArray<int32>& IncidentElements_i = IncidentElements[i];
380 for (int32 e = 0; e < IncidentElements_i.Num(); e++)
381 {
382 const int32 Elem = IncidentElements_i[e];
384 Lu[p] += element_contributions[(Elem * 4) + Local];
385 }
386 });
387}
388
389template<class T, class TV_INT, int d=3>
390T
392 const TArray<TV_INT>& Mesh,
393 const TArray<T>& De_inverse,
394 const TArray<T>& measure,
395 const TArray<T>& u)
396{
398 grad_Nie_hat[0] = { T(-1),T(-1),T(-1) };
399 grad_Nie_hat[1] = { T(1),T(0),T(0) };
400 grad_Nie_hat[2] = { T(0),T(1),T(0) };
401 grad_Nie_hat[3] = { T(0),T(0),T(1) };
402
403 //first compute element contributions in parallel
405
406 //PhysicsParallelForRange(Mesh.Num(), [&](const int32 eBegin, const int32 eEnd)
407 const int32 eBegin = 0;
408 const int32 eEnd = Mesh.Num();
409 {
410 for(int32 e=eBegin; e < eEnd; e++)
411 {
412 T Deinv[d * d]{
413 De_inverse[d * d * e + 0],
414 De_inverse[d * d * e + 1],
415 De_inverse[d * d * e + 2],
416 De_inverse[d * d * e + 3],
417 De_inverse[d * d * e + 4],
418 De_inverse[d * d * e + 5],
419 De_inverse[d * d * e + 6],
420 De_inverse[d * d * e + 7],
421 De_inverse[d * d * e + 8],
422 };
423 T De_inverse_transpose[d * d];
425
426 const TV_INT& Elem = Mesh[e];
428 for (int32 ie = 0; ie < d + 1; ie++)
429 {
431 for (int32 je = 0; je < d + 1; je++)
432 {
434
436 element_contributions[e] += u[Elem[ie]] * Ae_ieje * u[Elem[je]];
437 }
438 }
439 }
440 }/*,
441 100,
442 Mesh.Num() < 100);*/
443
444 //now gather from elements
445 T result = T(0);
446 for (int32 i = 0; i < Mesh.Num(); ++i)
447 {
448 result += element_contributions[i];
449 }
450 return T(.5) * result;
451}
452
453
454
455
456template <class T, class TV, class TV_INT, int d=3>
457void
459 const TArray<TV_INT>& Mesh,
460 const TArray<TV>& Vertices,
461 const TArray<TArray<int32>>& IncidentElements,
463 const TArray<int32>& Origins,
465 TArray<TV>& Directions,
467 const int32 MaxIt=100,
468 const T Tol=T(1e-7))
469{
470 // Define bc lambda
471 auto set_bcs = [&Origins, &Insertions](TArray<T>& minus_u_bc, const T scale, bool zero_non_boundary = true)
472 {
474 Fill(minus_u_bc, T(0));
475 // origin points have bc = scale
476 for (int32 i = 0; i < Origins.Num(); i++)
478 // insertion points have bc = 2*scale
479 for (int32 i = 0; i < Insertions.Num(); i++)
481 };
482
483 // Origin and insertion points are fixed
484 auto proj_bcs = [&Origins, &Insertions](TArray<T>& u)
485 {
486 for (int32 i = 0; i < Origins.Num(); i++)
487 u[Origins[i]] = T(0);
488 for (int32 i = 0; i < Insertions.Num(); i++)
489 u[Insertions[i]] = T(0);
490 };
491
492 TArray<T> u; u.SetNumZeroed(Vertices.Num());
493
494 // Initialize FEM meta data
497 Chaos::ComputeDeInverseAndElementMeasures<T>(Mesh, Vertices, De_inverse, measure);
498
499 // Set BCs and RHS
502 set_bcs(negative_u_bc, T(-1), true);
503
505 proj_bcs(rhs);
506
507 auto mult = [&](TArray<T>& out, const TArray<T>& in)
508 {
509 TArray<T> proj_in = in;
512 proj_bcs(out);
513 };
514
515 //solve system
516 Chaos::LanczosCG(mult, u, rhs, MaxIt, Tol, true);
517 set_bcs(u, T(1), false);
518
519 //compute directions from scalar gradient
520 Directions.SetNumUninitialized(Mesh.Num());
521 Fill(Directions, TV(0));
522 ScalarField = u;
523
525 grad_Nie_hat[0] = { T(-1),T(-1),T(-1) };
526 grad_Nie_hat[1] = { T(1),T(0),T(0) };
527 grad_Nie_hat[2] = { T(0),T(1),T(0) };
528 grad_Nie_hat[3] = { T(0),T(0),T(1) };
529
530 TV pseudo_direction = Vertices[Insertions[0]] - Vertices[Origins[0]];
531 pseudo_direction.Normalize();
532
533 PhysicsParallelFor(Mesh.Num(), [&](const int32 e)
534 {
535 T Deinv[d * d]{
536 De_inverse[d * d * e + 0],
537 De_inverse[d * d * e + 1],
538 De_inverse[d * d * e + 2],
539 De_inverse[d * d * e + 3],
540 De_inverse[d * d * e + 4],
541 De_inverse[d * d * e + 5],
542 De_inverse[d * d * e + 6],
543 De_inverse[d * d * e + 7],
544 De_inverse[d * d * e + 8],
545 };
546 T De_inverse_transpose[d * d];
548
549 const TV_INT& Elem = Mesh[e];
550 TV gradient(0);
552 for (size_t ie = 0; ie < d + 1; ie++)
553 {
555 gradient += grad_Nie * u[Elem[ie]];
556 }
557 const T Len = gradient.Length();
558 if (Len > T(1e-10))
559 {
560 Directions[e] = gradient * T(1) / Len;
561 }
562 else if (u[Mesh[e][0]] > 0)
563 {
564 Directions[e] = pseudo_direction;
565 }
566 else
567 {
568 Directions[e] = gradient;
569 }
570 });
571}
572
573// 9 point laplacian with dirichlet boundaries
574template<class TV, class T, bool NodalValues = false>
576 const TArray<TV>& U,
577 TArray<TV>& Lu)
578{
579 const TVec3<int32> Counts = NodalValues ? UniformGrid.NodeCounts() : UniformGrid.Counts();
580
581 const int32 XStride = Counts[1] * Counts[2];
582 const int32 YStride = Counts[2];
583 constexpr int32 ZStride = 1;
585
586 Fill(Lu, TV(0));
587
588 for (int32 I = 1; I < Counts.X - 1; ++I)
589 {
590 for (int32 J = 1; J < Counts.Y - 1; ++J)
591 {
592 for (int32 K = 1; K < Counts.Z - 1; ++K)
593 {
594 const int32 FlatIndex = I * XStride + J * YStride + K * ZStride;
595 Lu[FlatIndex] +=
596 (U[FlatIndex + XStride] - (T)2. * U[FlatIndex] + U[FlatIndex - XStride]) * OneOverDxSq[0] +
597 (U[FlatIndex + YStride] - (T)2. * U[FlatIndex] + U[FlatIndex - YStride]) * OneOverDxSq[1] +
598 (U[FlatIndex + ZStride] - (T)2. * U[FlatIndex] + U[FlatIndex - ZStride]) * OneOverDxSq[2];
599 }
600 }
601 }
602}
603
604// Solve Poisson on a Uniform Grid (with standard 9-point Laplacian).
605// Weights is a flattened array (using same indexing as UniformGrid and ArrayND) and the output solution.
606// InConstrainedNodes is a list of flattened index nodes that are boundary conditions. ConstrainedWeights is a parallel array of the constrained values.
607template<class TV, class T, bool NodalValues = false>
611 const int32 MaxItCG,
612 const TV CGTol,
613 TArray<TV>& Weights,
614 bool bCheckResidual = false,
616{
617 auto ProjectBCs = [&InConstrainedNodes](TArray<TV>& U)
618 {
619 for (int32 i = 0; i < InConstrainedNodes.Num(); i++)
620 {
621 U[InConstrainedNodes[i]] = (T)0.;
622 }
623 };
624
625 auto MultiplyLaplacian = [&ProjectBCs, &UniformGrid](TArray<TV>& LU, const TArray<TV>& U)
626 {
629 U,
630 LU);
631 ProjectBCs(LU);
632 };
633
634 Fill(Weights, TV(0));
635
637 InitialGuess.Init((TV)0., Weights.Num());
638 for (int32 i = 0; i < InConstrainedNodes.Num(); i++)
639 {
641 }
643 MinusResidual.Init((TV)0., Weights.Num());
645
647 MinusDw.Init((TV)0., Weights.Num());
649
650 for (int32 i = 0; i < InitialGuess.Num(); i++)
651 {
652 Weights[i] = InitialGuess[i] - MinusDw[i];
653 }
654}
655
656
657} // namespace Chaos
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
Definition UniformGrid.h:267
Definition Vector.h:1000
T X
Definition Vector.h:1168
T Z
Definition Vector.h:1170
T Y
Definition Vector.h:1169
Definition Vector.h:41
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void SetNumZeroed(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2340
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
void SetNumUninitialized(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2369
Definition SkeletalMeshComponent.h:307
TV RowMaj3x3Multiply(const T *A, const TV &x)
Definition Poisson.h:159
void ComputeDeInverseAndElementMeasures(const TArray< TV_INT > &Mesh, const TArray< TV > &X, TArray< T > &De_inverse, TArray< T > &measure)
Definition Poisson.h:197
T LaplacianEnergy(const TArray< TV_INT > &Mesh, const TArray< T > &De_inverse, const TArray< T > &measure, const TArray< T > &u)
Definition Poisson.h:391
void RowMaj3x3SetRow(T *A, const int32 i, const T *Values)
Definition Poisson.h:39
void PoissonSolve(const TArray< int32 > &InConstrainedNodes, const TArray< T > &ConstrainedWeights, const TArray< TV_INT > &Mesh, const TArray< TV > &X, const int32 MaxItCG, const T CGTol, TArray< T > &Weights)
Definition Poisson.h:257
void RowMaj3x3Inverse(const T Det, const T A0, const T A1, const T A2, const T A3, const T A4, const T A5, const T A6, const T A7, const T A8, T *Inv)
Definition Poisson.h:109
int32 MinFlatIndex(const TArray< int32 > &ElemIdx, const TArray< int32 > &LocalIdx)
Definition Poisson.h:245
T RowMaj3x3Determinant(const T A0, const T A1, const T A2, const T A3, const T A4, const T A5, const T A6, const T A7, const T A8)
Definition Poisson.h:95
TV RowMaj3x3RobustSolveLinearSystem(const T *A, const TV &b)
Definition Poisson.h:173
@ X
Definition SimulationModuleBase.h:152
void RowMaj3x3GetCol(T *A, const int32 j, TV &Col)
Definition Poisson.h:84
void CHAOS_API PhysicsParallelFor(int32 InNum, TFunctionRef< void(int32)> InCallable, bool bForceSingleThreaded=false)
Definition Parallel.cpp:55
void RowMaj3x3SetCol(T *A, const int32 j, const T *Values)
Definition Poisson.h:66
void RowMaj3x3Transpose(const T *A, T *Transpose)
Definition Poisson.h:147
void ComputeFiberField(const TArray< TV_INT > &Mesh, const TArray< TV > &Vertices, const TArray< TArray< int32 > > &IncidentElements, const TArray< TArray< int32 > > &IncidentElementsLocalIndex, const TArray< int32 > &Origins, const TArray< int32 > &Insertions, TArray< TV > &Directions, TArray< T > &ScalarField, const int32 MaxIt=100, const T Tol=T(1e-7))
Definition Poisson.h:458
void LanczosCG(Func multiplyA, TArray< T > &x, const TArray< T > &b, const int max_it, const T res=1e-4, bool check_residual=false, int min_parallel_batch_size=1000)
Definition Krylov.h:14
const T & RowMaj3x3Get(const T *A, const int32 i, const int32 j)
Definition Poisson.h:25
void RowMaj3x3Set(T *A, const int32 i, const int32 j, const T Value)
Definition Poisson.h:19
void Laplacian(const TArray< TV_INT > &Mesh, const TArray< TArray< int32 > > &IncidentElements, const TArray< TArray< int32 > > &IncidentElementsLocalIndex, const TArray< T > &De_inverse, const TArray< T > &measure, const TArray< T > &u, TArray< T > &Lu)
Definition Poisson.h:318
void RowMaj3x3GetRow(T *A, const int32 i, TV &Row)
Definition Poisson.h:55
static constexpr UE_FORCEINLINE_HINT T Max3(const T A, const T B, const T C)
Definition UnrealMathUtility.h:551
Definition NumericLimits.h:41