Skip to content
Merged
Show file tree
Hide file tree
Changes from 72 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
90da431
[BUG FIX] Preserve external forces across sub-steps. (#1290)
LeonLiu4 Jun 20, 2025
0864103
[MISC] Reduce warning messages. (#1294)
YilingQiao Jun 20, 2025
8d07248
[MISC] Update default FEM damping 45.0 -> 0.0 (#1288)
Milotrince Jun 20, 2025
6d9f319
bvh query
Libero0809 Jun 4, 2025
197453b
Wrap aabb with python AABB class
Libero0809 Jun 5, 2025
bf0ee25
move query result batch dim
Libero0809 Jun 6, 2025
d385da6
init
Libero0809 Jun 10, 2025
fe432f0
Update bvh.py
duburcqa Jun 10, 2025
b1a7d2d
tet plane detection
Libero0809 Jun 11, 2025
82ffb7e
worked but far from good
Libero0809 Jun 14, 2025
0d564a2
add damping
Libero0809 Jun 16, 2025
1241c5b
add test
Libero0809 Jun 16, 2025
bd5aa0f
change test fem to sapcoupler
Libero0809 Jun 18, 2025
122e221
change test name
Libero0809 Jun 18, 2025
2778529
code cleanup & bug fix
Libero0809 Jun 18, 2025
54d5646
fix test
Libero0809 Jun 19, 2025
e74be79
fix test
Libero0809 Jun 20, 2025
bf60281
update doc for sap
Libero0809 Jun 20, 2025
604aef5
corotated
Libero0809 Jun 19, 2025
3845104
init
Libero0809 Jun 20, 2025
5cc72a0
fix bug in bvh
Libero0809 Jun 21, 2025
281dac3
debugging
Libero0809 Jun 24, 2025
2d38888
tet tet intersection
Libero0809 Jun 25, 2025
d5208f8
framework for ipc
Libero0809 Jun 25, 2025
f498d0f
remove the ipc part for cleaness
Libero0809 Jun 25, 2025
07e2112
Merge branch 'main' into bvh
Libero0809 Jun 25, 2025
d6ca8e0
pair detect ready
Libero0809 Jun 26, 2025
2c24e59
add gpu test
Libero0809 Jun 26, 2025
d7889fd
change compute bound to layered reduction
Libero0809 Jun 26, 2025
593892b
Merge branch 'main' into bvh
Libero0809 Jun 26, 2025
d33f8dc
make tests faster
Libero0809 Jun 26, 2025
624eed4
code clean up
Libero0809 Jun 26, 2025
98d30ab
removed unused field
Libero0809 Jun 26, 2025
d701966
Merge branch 'bvh' into self_collision
Libero0809 Jun 26, 2025
1d14882
refactor
Libero0809 Jun 27, 2025
bf3e08a
optimize performance
Libero0809 Jun 28, 2025
ed4c241
exact linesearch
Libero0809 Jul 4, 2025
83374ff
refactor
Libero0809 Jul 8, 2025
5013d26
add tests
Libero0809 Jul 8, 2025
94b84ba
Merge branch 'main' into self_collision
Libero0809 Jul 8, 2025
35dc136
small bug
Libero0809 Jul 8, 2025
c5f8320
init
Libero0809 Jul 9, 2025
995cb7c
code cleanup
Libero0809 Jul 10, 2025
7a9697d
Merge branch 'self_collision_debug' into fem_rigid
Libero0809 Jul 10, 2025
d2344bc
fix merge
Libero0809 Jul 10, 2025
8774db2
refactor
Libero0809 Jul 10, 2025
8897550
debug pcg
Libero0809 Jul 10, 2025
75df4e5
remove_debug
Libero0809 Jul 10, 2025
9d00be9
fix bug
Libero0809 Jul 10, 2025
b783e1f
merge kernels
Libero0809 Jul 11, 2025
03e0d93
working on linesearch
Libero0809 Jul 12, 2025
8859d24
rigid vert floor contact
Libero0809 Jul 14, 2025
247ea84
debugging
Libero0809 Jul 16, 2025
a8b2c69
debug
Libero0809 Jul 16, 2025
bb1bad3
change rigid
Libero0809 Jul 17, 2025
e0b7fc2
add rigid coupling
Libero0809 Jul 24, 2025
17baa9f
remove debug
Libero0809 Jul 24, 2025
5833ede
Merge branch 'main' into fem_rigid_debug
Libero0809 Jul 24, 2025
ea65d89
add tests
Libero0809 Jul 25, 2025
4c06b6b
fix import
Libero0809 Jul 25, 2025
8c8f466
Merge branch 'main' into fem_rigid_debug
Libero0809 Jul 29, 2025
14aa259
clean up
Libero0809 Aug 13, 2025
33d9eac
Merge branch 'main' into fem_rigid_debug
Libero0809 Aug 13, 2025
7316c04
cleanup
Libero0809 Aug 13, 2025
b46500d
Merge branch 'main' into fem_rigid_debug
Libero0809 Aug 13, 2025
0e6e688
code cleanup
Libero0809 Aug 13, 2025
016390b
Merge branch 'main' into fem_rigid_debug
Libero0809 Aug 13, 2025
62f38ea
fix test query
Libero0809 Aug 13, 2025
80bcffd
add tests
Libero0809 Jul 28, 2025
8d86e28
fix tests and bug
Libero0809 Aug 13, 2025
735b4bb
Merge branch 'main' into fem-fixed-constraint
Libero0809 Aug 14, 2025
250829b
code cleanup
Libero0809 Aug 14, 2025
acae2c5
fix i_vs
Libero0809 Aug 14, 2025
a0807da
i_vs
Libero0809 Aug 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 70 additions & 28 deletions genesis/engine/couplers/sap_coupler.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,18 +729,16 @@ def compute_rigid_pcg_matrix_vector_product(self):
)

@ti.func
def compute_elastic_products(self, i_b, i_e, B, s, i_v0, i_v1, i_v2, i_v3, src):
def compute_elastic_products(self, i_b, i_e, S, i_vs, src):
p9 = ti.Vector.zero(gs.ti_float, 9)
for i in ti.static(range(3)):
p9[i * 3 : i * 3 + 3] = (
B[0, i] * src[i_b, i_v0] + B[1, i] * src[i_b, i_v1] + B[2, i] * src[i_b, i_v2] + s[i] * src[i_b, i_v3]
)
for i, j in ti.static(ti.ndrange(3, 4)):
p9[i * 3 : i * 3 + 3] = p9[i * 3 : i * 3 + 3] + (S[j, i] * src[i_b, i_vs[j]])

H9_p9 = ti.Vector.zero(gs.ti_float, 9)
for i in ti.static(range(3)):
H9_p9[i * 3 : i * 3 + 3] = (
self.fem_solver.elements_el_hessian[i_b, i, 0, i_e] @ p9[0:3]
+ self.fem_solver.elements_el_hessian[i_b, i, 1, i_e] @ p9[3:6]
+ self.fem_solver.elements_el_hessian[i_b, i, 2, i_e] @ p9[6:9]

for i, j in ti.static(ti.ndrange(3, 3)):
H9_p9[i * 3 : i * 3 + 3] = H9_p9[i * 3 : i * 3 + 3] + (
self.fem_solver.elements_el_hessian[i_b, i, j, i_e] @ p9[j * 3 : j * 3 + 3]
)
return p9, H9_p9

Expand All @@ -767,16 +765,21 @@ def compute_fem_matrix_vector_product(self, src, dst, active):
continue
V_dt2 = self.fem_solver.elements_i[i_e].V * dt2
B = self.fem_solver.elements_i[i_e].B
s = -B[0, :] - B[1, :] - B[2, :] # s is the negative sum of B rows
i_v0, i_v1, i_v2, i_v3 = self.fem_solver.elements_i[i_e].el2v
S = ti.Matrix.zero(gs.ti_float, 4, 3)
S[:3, :] = B
S[3, :] = -B[0, :] - B[1, :] - B[2, :]
i_v = self.fem_solver.elements_i[i_e].el2v

if ti.static(self.fem_solver._enable_vertex_constraints):
for i in ti.static(range(4)):
if self.fem_solver.vertex_constraints.is_constrained[i_v[i], i_b]:
S[i, :] = ti.Vector.zero(gs.ti_float, 3)

_, new_p9 = self.compute_elastic_products(i_b, i_e, B, s, i_v0, i_v1, i_v2, i_v3, src)
_, new_p9 = self.compute_elastic_products(i_b, i_e, S, i_v, src)
# atomic
scale = V_dt2 * damping_beta_factor
dst[i_b, i_v0] += (B[0, 0] * new_p9[0:3] + B[0, 1] * new_p9[3:6] + B[0, 2] * new_p9[6:9]) * scale
dst[i_b, i_v1] += (B[1, 0] * new_p9[0:3] + B[1, 1] * new_p9[3:6] + B[1, 2] * new_p9[6:9]) * scale
dst[i_b, i_v2] += (B[2, 0] * new_p9[0:3] + B[2, 1] * new_p9[3:6] + B[2, 2] * new_p9[6:9]) * scale
dst[i_b, i_v3] += (s[0] * new_p9[0:3] + s[1] * new_p9[3:6] + s[2] * new_p9[6:9]) * scale
for i in ti.static(range(4)):
dst[i_b, i_v[i]] += (S[i, 0] * new_p9[0:3] + S[i, 1] * new_p9[3:6] + S[i, 2] * new_p9[6:9]) * scale

def init_pcg_solve(self):
self.init_pcg_state()
Expand Down Expand Up @@ -1101,10 +1104,17 @@ def compute_fem_energy(self, i_step: ti.i32, energy: ti.template()):

V_dt2 = self.fem_solver.elements_i[i_e].V * dt2
B = self.fem_solver.elements_i[i_e].B
s = -B[0, :] - B[1, :] - B[2, :] # s is the negative sum of B rows
i_v0, i_v1, i_v2, i_v3 = self.fem_solver.elements_i[i_e].el2v
S = ti.Matrix.zero(gs.ti_float, 4, 3)
S[:3, :] = B
S[3, :] = -B[0, :] - B[1, :] - B[2, :]
i_v = self.fem_solver.elements_i[i_e].el2v

p9, H9_p9 = self.compute_elastic_products(i_b, i_e, B, s, i_v0, i_v1, i_v2, i_v3, self.fem_state_v.v_diff)
if ti.static(self.fem_solver._enable_vertex_constraints):
for i in ti.static(range(4)):
if self.fem_solver.vertex_constraints.is_constrained[i_v[i], i_b]:
S[i, :] = ti.Vector.zero(gs.ti_float, 3)

p9, H9_p9 = self.compute_elastic_products(i_b, i_e, S, i_v, self.fem_state_v.v_diff)
energy[i_b] += 0.5 * p9.dot(H9_p9) * damping_beta_factor * V_dt2

@ti.func
Expand Down Expand Up @@ -1991,15 +2001,23 @@ def add_Jt_x(self, y, i_p, x):
i_g = self.contact_pairs[i_p].geom_idx
for i in ti.static(range(4)):
i_v = self.fem_solver.elements_i[i_g].el2v[i]
y[i_b, i_v] += self.contact_pairs[i_p].barycentric[i] * x
if ti.static(self.fem_solver._enable_vertex_constraints):
if not self.fem_solver.vertex_constraints.is_constrained[i_v, i_b]:
y[i_b, i_v] += self.contact_pairs[i_p].barycentric[i] * x
else:
y[i_b, i_v] += self.contact_pairs[i_p].barycentric[i] * x

@ti.func
def add_Jt_A_J_diag3x3(self, y, i_p, A):
i_b = self.contact_pairs[i_p].batch_idx
i_g = self.contact_pairs[i_p].geom_idx
for i in ti.static(range(4)):
i_v = self.fem_solver.elements_i[i_g].el2v[i]
y[i_b, i_v] += self.contact_pairs[i_p].barycentric[i] ** 2 * A
if ti.static(self.fem_solver._enable_vertex_constraints):
if not self.fem_solver.vertex_constraints.is_constrained[i_v, i_b]:
y[i_b, i_v] += self.contact_pairs[i_p].barycentric[i] ** 2 * A
else:
y[i_b, i_v] += self.contact_pairs[i_p].barycentric[i] ** 2 * A

@ti.func
def compute_delassus(self, i_p):
Expand Down Expand Up @@ -2302,10 +2320,18 @@ def add_Jt_x(self, y, i_p, x):
x_ = world @ x
for i in ti.static(range(4)):
i_v = self.fem_solver.elements_i[i_g0].el2v[i]
y[i_b, i_v] += self.contact_pairs[i_p].barycentric0[i] * x_
if ti.static(self.fem_solver._enable_vertex_constraints):
if not self.fem_solver.vertex_constraints.is_constrained[i_v, i_b]:
y[i_b, i_v] += self.contact_pairs[i_p].barycentric0[i] * x_
else:
y[i_b, i_v] += self.contact_pairs[i_p].barycentric0[i] * x_
for i in ti.static(range(4)):
i_v = self.fem_solver.elements_i[i_g1].el2v[i]
y[i_b, i_v] -= self.contact_pairs[i_p].barycentric1[i] * x_
if ti.static(self.fem_solver._enable_vertex_constraints):
if not self.fem_solver.vertex_constraints.is_constrained[i_v, i_b]:
y[i_b, i_v] -= self.contact_pairs[i_p].barycentric1[i] * x_
else:
y[i_b, i_v] -= self.contact_pairs[i_p].barycentric1[i] * x_

@ti.func
def add_Jt_A_J_diag3x3(self, y, i_p, A):
Expand All @@ -2318,10 +2344,18 @@ def add_Jt_A_J_diag3x3(self, y, i_p, A):
B_ = world @ A @ world.transpose()
for i in ti.static(range(4)):
i_v = self.fem_solver.elements_i[i_g0].el2v[i]
y[i_b, i_v] += self.contact_pairs[i_p].barycentric0[i] ** 2 * B_
if ti.static(self.fem_solver._enable_vertex_constraints):
if not self.fem_solver.vertex_constraints.is_constrained[i_v, i_b]:
y[i_b, i_v] += self.contact_pairs[i_p].barycentric0[i] ** 2 * B_
else:
y[i_b, i_v] += self.contact_pairs[i_p].barycentric0[i] ** 2 * B_
for i in ti.static(range(4)):
i_v = self.fem_solver.elements_i[i_g1].el2v[i]
y[i_b, i_v] += self.contact_pairs[i_p].barycentric1[i] ** 2 * B_
if ti.static(self.fem_solver._enable_vertex_constraints):
if not self.fem_solver.vertex_constraints.is_constrained[i_v, i_b]:
y[i_b, i_v] += self.contact_pairs[i_p].barycentric1[i] ** 2 * B_
else:
y[i_b, i_v] += self.contact_pairs[i_p].barycentric1[i] ** 2 * B_

@ti.func
def compute_delassus(self, i_p):
Expand Down Expand Up @@ -2408,13 +2442,21 @@ def compute_Jx(self, i_p, x):
def add_Jt_x(self, y, i_p, x):
i_b = self.contact_pairs[i_p].batch_idx
i_g = self.contact_pairs[i_p].geom_idx
y[i_b, i_g] += x
if ti.static(self.fem_solver._enable_vertex_constraints):
if not self.fem_solver.vertex_constraints.is_constrained[i_g, i_b]:
y[i_b, i_g] += x
else:
y[i_b, i_g] += x

@ti.func
def add_Jt_A_J_diag3x3(self, y, i_p, A):
i_b = self.contact_pairs[i_p].batch_idx
i_g = self.contact_pairs[i_p].geom_idx
y[i_b, i_g] += A
if ti.static(self.fem_solver._enable_vertex_constraints):
if not self.fem_solver.vertex_constraints.is_constrained[i_g, i_b]:
y[i_b, i_g] += A
else:
y[i_b, i_g] += A

@ti.func
def compute_delassus(self, i_p):
Expand Down
5 changes: 3 additions & 2 deletions genesis/engine/entities/fem_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -803,8 +803,9 @@ def set_vertex_constraints(
List of environment indices to apply the constraints to. If None, applies to all environments.
"""
if self._solver._use_implicit_solver:
gs.logger.warning("Ignoring vertex constraint; unsupported with FEM implicit solver.")
return
if not self._solver._enable_vertex_constraints:
gs.logger.warning("Ignoring vertex constraint; FEM implicit solver needs to enable vertex constraints.")
return

if not self._solver._constraints_initialized:
self._solver.init_constraints()
Expand Down
Loading
Loading