@@ -595,6 +595,21 @@ def compute_ele_hessian_gradient(self, f: ti.i32):
595595 hessian_field = self .elements_el_hessian ,
596596 )
597597
598+ @ti .func
599+ def _func_compute_element_mapping_matrix (self , i_vs , B , i_b ):
600+ """
601+ Compute the element mapping matrix S for an element.
602+ """
603+ S = ti .Matrix .zero (gs .ti_float , 4 , 3 )
604+ S [:3 , :] = B
605+ S [3 , :] = - B [0 , :] - B [1 , :] - B [2 , :]
606+
607+ if ti .static (self ._enable_vertex_constraints ):
608+ for i in ti .static (range (4 )):
609+ if self .vertex_constraints .is_constrained [i_vs [i ], i_b ]:
610+ S [i , :] = ti .Vector .zero (gs .ti_float , 3 )
611+ return S
612+
598613 @ti .func
599614 def _func_compute_ele_energy (self , f : ti .i32 ):
600615 """
@@ -622,21 +637,14 @@ def _func_compute_ele_energy(self, f: ti.i32):
622637 # add linearized damping energy
623638 if self ._damping_beta > gs .EPS :
624639 damping_beta_over_dt = self ._damping_beta / self ._substep_dt
625- i_v = self .elements_i [i_e ].el2v
626- S = ti .Matrix .zero (gs .ti_float , 4 , 3 )
640+ i_vs = self .elements_i [i_e ].el2v
627641 B = self .elements_i [i_e ].B
628- S [:3 , :] = B
629- S [3 , :] = - B [0 , :] - B [1 , :] - B [2 , :]
630-
631- if ti .static (self ._enable_vertex_constraints ):
632- for i in ti .static (range (4 )):
633- if self .vertex_constraints .is_constrained [i_v [i ], i_b ]:
634- S [i , :] = ti .Vector .zero (gs .ti_float , 3 )
642+ S = self ._func_compute_element_mapping_matrix (i_vs , B , i_b )
635643
636644 x_diff = ti .Vector .zero (gs .ti_float , 12 )
637645 for i in ti .static (range (4 )):
638646 x_diff [i * 3 : i * 3 + 3 ] = (
639- self .elements_v [f + 1 , i_v [i ], i_b ].pos - self .elements_v [f , i_v [i ], i_b ].pos
647+ self .elements_v [f + 1 , i_vs [i ], i_b ].pos - self .elements_v [f , i_vs [i ], i_b ].pos
640648 )
641649 St_x_diff = ti .Vector .zero (gs .ti_float , 9 )
642650 for i , j in ti .static (ti .ndrange (3 , 4 )):
@@ -657,17 +665,17 @@ def accumulate_vertex_force_preconditioner(self, f: ti.i32):
657665 damping_beta_over_dt = self ._damping_beta / self ._substep_dt
658666 damping_beta_factor = damping_beta_over_dt + 1.0
659667 # inertia
660- for i_b , i_v in ti .ndrange (self ._B , self .n_vertices ):
668+ for i_b , i_vs in ti .ndrange (self ._B , self .n_vertices ):
661669 if not self .batch_active [i_b ]:
662670 continue
663- self .elements_v_energy [i_b , i_v ].force = - self .elements_v_info [i_v ].mass_over_dt2 * (
664- (self .elements_v [f + 1 , i_v , i_b ].pos - self .elements_v_energy [i_b , i_v ].inertia )
665- + (self .elements_v [f + 1 , i_v , i_b ].pos - self .elements_v [f , i_v , i_b ].pos ) * damping_alpha_dt
671+ self .elements_v_energy [i_b , i_vs ].force = - self .elements_v_info [i_vs ].mass_over_dt2 * (
672+ (self .elements_v [f + 1 , i_vs , i_b ].pos - self .elements_v_energy [i_b , i_vs ].inertia )
673+ + (self .elements_v [f + 1 , i_vs , i_b ].pos - self .elements_v [f , i_vs , i_b ].pos ) * damping_alpha_dt
666674 )
667- self .pcg_state_v [i_b , i_v ].diag3x3 = ti .Matrix .zero (gs .ti_float , 3 , 3 )
675+ self .pcg_state_v [i_b , i_vs ].diag3x3 = ti .Matrix .zero (gs .ti_float , 3 , 3 )
668676 for i in ti .static (range (3 )):
669- self .pcg_state_v [i_b , i_v ].diag3x3 [i , i ] = (
670- self .elements_v_info [i_v ].mass_over_dt2 * damping_alpha_factor
677+ self .pcg_state_v [i_b , i_vs ].diag3x3 [i , i ] = (
678+ self .elements_v_info [i_vs ].mass_over_dt2 * damping_alpha_factor
671679 )
672680
673681 # elastic
@@ -677,27 +685,19 @@ def accumulate_vertex_force_preconditioner(self, f: ti.i32):
677685 V = self .elements_i [i_e ].V
678686 B = self .elements_i [i_e ].B
679687 gradient = self .elements_el_energy [i_b , i_e ].gradient
680- i_v = self .elements_i [i_e ].el2v
681- S = ti .Matrix .zero (gs .ti_float , 4 , 3 )
682- S [:3 , :] = B
683- S [3 , :] = - B [0 , :] - B [1 , :] - B [2 , :]
684-
685- if ti .static (self ._enable_vertex_constraints ):
686- for i in ti .static (range (4 )):
687- if self .vertex_constraints .is_constrained [i_v [i ], i_b ]:
688- S [i , :] = ti .Vector .zero (gs .ti_float , 3 )
689-
688+ i_vs = self .elements_i [i_e ].el2v
689+ S = self ._func_compute_element_mapping_matrix (i_vs , B , i_b )
690690 force = - V * gradient @ S .transpose ()
691691
692692 # atomic
693693 for i in ti .static (range (4 )):
694- self .elements_v_energy [i_b , i_v [i ]].force += force [:, i ]
694+ self .elements_v_energy [i_b , i_vs [i ]].force += force [:, i ]
695695
696696 if self ._damping_beta > gs .EPS :
697697 x_diff = ti .Vector .zero (gs .ti_float , 12 )
698698 for i in ti .static (range (4 )):
699699 x_diff [i * 3 : i * 3 + 3 ] = (
700- self .elements_v [f + 1 , i_v [i ], i_b ].pos - self .elements_v [f , i_v [i ], i_b ].pos
700+ self .elements_v [f + 1 , i_vs [i ], i_b ].pos - self .elements_v [f , i_vs [i ], i_b ].pos
701701 )
702702 St_x_diff = ti .Vector .zero (gs .ti_float , 9 )
703703 for i , j in ti .static (ti .ndrange (3 , 4 )):
@@ -712,22 +712,22 @@ def accumulate_vertex_force_preconditioner(self, f: ti.i32):
712712 for i , j in ti .static (ti .ndrange (4 , 3 )):
713713 S_H_St_x_diff [i * 3 : i * 3 + 3 ] += S [i , j ] * H_St_x_diff [j * 3 : j * 3 + 3 ]
714714 for i in ti .static (range (4 )):
715- self .elements_v_energy [i_b , i_v [i ]].force += (
715+ self .elements_v_energy [i_b , i_vs [i ]].force += (
716716 - damping_beta_over_dt * V * S_H_St_x_diff [i * 3 : i * 3 + 3 ]
717717 )
718718
719719 # diagonal 3-by-3 block of hessian
720720 for k , i , j in ti .ndrange (4 , 3 , 3 ):
721- self .pcg_state_v [i_b , i_v [k ]].diag3x3 += (
721+ self .pcg_state_v [i_b , i_vs [k ]].diag3x3 += (
722722 V * damping_beta_factor * S [k , i ] * S [k , j ] * self .elements_el_hessian [i_b , i , j , i_e ]
723723 )
724724
725725 # inverse
726- for i_b , i_v in ti .ndrange (self ._B , self .n_vertices ):
726+ for i_b , i_vs in ti .ndrange (self ._B , self .n_vertices ):
727727 if not self .batch_active [i_b ]:
728728 continue
729729 # Use 3-by-3 diagonal block inverse for preconditioner
730- self .pcg_state_v [i_b , i_v ].prec = self .pcg_state_v [i_b , i_v ].diag3x3 .inverse ()
730+ self .pcg_state_v [i_b , i_vs ].prec = self .pcg_state_v [i_b , i_vs ].diag3x3 .inverse ()
731731
732732 # Other options for preconditioner:
733733 # Uncomment one of the following lines to test different preconditioners
@@ -745,32 +745,25 @@ def compute_Ap(self):
745745 damping_alpha_factor = damping_alpha_dt + 1.0
746746 damping_beta_over_dt = self ._damping_beta / self ._substep_dt
747747 damping_beta_factor = damping_beta_over_dt + 1.0
748- for i_b , i_v in ti .ndrange (self ._B , self .n_vertices ):
748+ for i_b , i_vs in ti .ndrange (self ._B , self .n_vertices ):
749749 if not self .batch_pcg_active [i_b ]:
750750 continue
751- self .pcg_state_v [i_b , i_v ].Ap = (
752- self .elements_v_info [i_v ].mass_over_dt2 * damping_alpha_factor * self .pcg_state_v [i_b , i_v ].p
751+ self .pcg_state_v [i_b , i_vs ].Ap = (
752+ self .elements_v_info [i_vs ].mass_over_dt2 * damping_alpha_factor * self .pcg_state_v [i_b , i_vs ].p
753753 )
754754
755755 for i_b , i_e in ti .ndrange (self ._B , self .n_elements ):
756756 if not self .batch_pcg_active [i_b ]:
757757 continue
758758 V = self .elements_i [i_e ].V
759759 B = self .elements_i [i_e ].B
760- i_v = self .elements_i [i_e ].el2v
761- S = ti .Matrix .zero (gs .ti_float , 4 , 3 )
762- S [:3 , :] = B
763- S [3 , :] = - B [0 , :] - B [1 , :] - B [2 , :]
764-
765- if ti .static (self ._enable_vertex_constraints ):
766- for i in ti .static (range (4 )):
767- if self .vertex_constraints .is_constrained [i_v [i ], i_b ]:
768- S [i , :] = ti .Vector .zero (gs .ti_float , 3 )
760+ i_vs = self .elements_i [i_e ].el2v
761+ S = self ._func_compute_element_mapping_matrix (i_vs , B , i_b )
769762
770763 p9 = ti .Vector ([0.0 ] * 9 , dt = gs .ti_float )
771764
772765 for i , j in ti .static (ti .ndrange (3 , 4 )):
773- p9 [i * 3 : i * 3 + 3 ] = p9 [i * 3 : i * 3 + 3 ] + S [j , i ] * self .pcg_state_v [i_b , i_v [j ]].p
766+ p9 [i * 3 : i * 3 + 3 ] = p9 [i * 3 : i * 3 + 3 ] + S [j , i ] * self .pcg_state_v [i_b , i_vs [j ]].p
774767
775768 new_p9 = ti .Vector ([0.0 ] * 9 , dt = gs .ti_float )
776769
@@ -781,7 +774,7 @@ def compute_Ap(self):
781774
782775 # atomic
783776 for i in ti .static (range (4 )):
784- self .pcg_state_v [i_b , i_v [i ]].Ap += (
777+ self .pcg_state_v [i_b , i_vs [i ]].Ap += (
785778 (S [i , 0 ] * new_p9 [0 :3 ] + S [i , 1 ] * new_p9 [3 :6 ] + S [i , 2 ] * new_p9 [6 :9 ]) * V * damping_beta_factor
786779 )
787780
0 commit comments