@@ -35,6 +35,7 @@ class Elastic(Base):
3535 Constitutive model to use for stress computation. Options are:
3636 - 'linear': Linear elasticity model
3737 - 'stable_neohookean': A numerically stable Neo-Hookean model
38+ - 'linear_corotated': Linear corotated elasticity model
3839 Default is 'linear'.
3940 """
4041
@@ -63,11 +64,28 @@ def __init__(
6364 self .hessian_invariant = False
6465 if model == "stable_neohooken" :
6566 gs .logger .warning ("The 'stable_neohooken' model is deprecated. Use 'stable_neohookean' instead." )
67+ elif model == "linear_corotated" :
68+ self .build = self .build_linear_corotated
69+ self .pre_compute = self .pre_compute_linear_corotated
70+ self .update_stress = self .update_stress_linear_corotated
71+ self .compute_energy_gradient_hessian = self .compute_energy_gradient_hessian_linear_corotated
72+ self .compute_energy_gradient = self .compute_energy_gradient_linear_corotated
73+ self .compute_energy = self .compute_energy_linear_corotated
74+ self .hessian_static = False
6675 else :
6776 gs .raise_exception (f"Unrecognized constitutive model: { model } " )
6877
6978 self ._model = model
7079
80+ def build_linear_corotated (self , fem_solver ):
81+ self .R = ti .field (dtype = gs .ti_mat3 , shape = (fem_solver ._B , fem_solver .n_elements ))
82+
83+ @ti .func
84+ def pre_compute_linear_corotated (self , J , F , i_e , i_b ):
85+ U , S , V = ti .svd (F )
86+ R = U @ V .transpose ()
87+ self .R [i_b , i_e ] = R
88+
7189 @ti .func
7290 def update_stress_linear (self , mu , lam , J , F , actu , m_dir ):
7391 I = ti .Matrix .identity (dt = gs .ti_float , n = 3 )
@@ -87,6 +105,10 @@ def update_stress_stable_neohookean(self, mu, lam, J, F, actu, m_dir):
87105
88106 return stress
89107
108+ @ti .func
109+ def update_stress_linear_corotated (self , mu , lam , J , F , actu , m_dir ):
110+ raise NotImplementedError ("Linear corotated stress update is not implemented yet." )
111+
90112 @ti .func
91113 def compute_energy_gradient_hessian_linear (self , mu , lam , J , F , actu , m_dir , i_e , i_b , hessian_field ):
92114 """
@@ -197,7 +219,7 @@ def compute_energy_gradient_linear(self, mu, lam, J, F, actu, m_dir, i_e, i_b):
197219 return energy , gradient
198220
199221 @ti .func
200- def compute_energy_linear (self , mu , lam , J , F , actu , m_dir ):
222+ def compute_energy_linear (self , mu , lam , J , F , actu , m_dir , i_e , i_b ):
201223 """
202224 Compute the energy for linear elasticity.
203225
@@ -316,7 +338,7 @@ def compute_energy_gradient_stable_neohookean(self, mu, lam, J, F, actu, m_dir,
316338 raise NotImplementedError ("Gradient computation is not implemented for stable_neohookean model." )
317339
318340 @ti .func
319- def compute_energy_stable_neohookean (self , mu , lam , J , F , actu , m_dir ):
341+ def compute_energy_stable_neohookean (self , mu , lam , J , F , actu , m_dir , i_e , i_b ):
320342 """
321343 Compute the energy for the stable Neo-Hookean model.
322344
@@ -354,6 +376,153 @@ def compute_energy_stable_neohookean(self, mu, lam, J, F, actu, m_dir):
354376
355377 return energy
356378
379+ @ti .func
380+ def compute_energy_gradient_hessian_linear_corotated (self , mu , lam , J , F , actu , m_dir , i_e , i_b , hessian_field ):
381+ """
382+ Compute the energy, gradient, and Hessian for linear elasticity.
383+
384+ Parameters
385+ ----------
386+ mu: float
387+ The first Lame parameter (shear modulus).
388+ lam: float
389+ The second Lame parameter (related to volume change).
390+ J: float
391+ The determinant of the deformation gradient F.
392+ F: ti.Matrix
393+ The deformation gradient matrix.
394+ actu: ti.Matrix
395+ The activation matrix (not used in linear elasticity).
396+ m_dir: ti.Matrix
397+ The material direction (not used in linear elasticity).
398+ hessian_field: ti.Matrix
399+ The Hessian of the energy with respect to the deformation gradient F.
400+
401+ Returns
402+ -------
403+ energy: float
404+ The computed energy.
405+ gradient: ti.Matrix
406+ The gradient of the energy with respect to the deformation gradient F.
407+
408+ Notes
409+ -------
410+ This implementation assumes small deformations and linear stress-strain relationship.
411+ It is adapted from the HOBAKv1 implementation for linear elasticity:
412+ https://github.com/theodorekim/HOBAKv1/blob/main/src/Hyperelastic/Volume/LINEAR.cpp
413+
414+ """
415+ R = self .R [i_b , i_e ]
416+ F_hat = R .transpose () @ F
417+ # E = 1/2(F_hat + F_hat.transpose()) - I
418+ eps = 0.5 * (F_hat + F_hat .transpose ())
419+ for i in ti .static (range (3 )):
420+ eps [i , i ] -= 1.0
421+ trEps = eps .trace ()
422+ energy = mu * eps .norm_sqr () + 0.5 * lam * trEps ** 2
423+
424+ gradient = 2.0 * mu * R @ eps + lam * trEps * R
425+
426+ # Zero out the matrix
427+ for i in ti .static (ti .grouped (ti .ndrange (3 , 3 ))):
428+ hessian_field [i_b , i , i_e ].fill (0.0 )
429+
430+ # Identity part
431+ for i , k in ti .static (ti .ndrange (3 , 3 )):
432+ hessian_field [i_b , i , i , i_e ][k , k ] = mu
433+
434+ for i , j , alpha , beta in ti .static (ti .ndrange (3 , 3 , 3 , 3 )):
435+ hessian_field [i_b , j , beta , i_e ][i , alpha ] += mu * R [i , beta ] * R [alpha , j ] + lam * R [alpha , beta ] * R [i , j ]
436+
437+ return energy , gradient
438+
439+ @ti .func
440+ def compute_energy_gradient_linear_corotated (self , mu , lam , J , F , actu , m_dir , i_e , i_b ):
441+ """
442+ Compute the energy, gradient for linear elasticity.
443+
444+ Parameters
445+ ----------
446+ mu: float
447+ The first Lame parameter (shear modulus).
448+ lam: float
449+ The second Lame parameter (related to volume change).
450+ J: float
451+ The determinant of the deformation gradient F.
452+ F: ti.Matrix
453+ The deformation gradient matrix.
454+ actu: ti.Matrix
455+ The activation matrix (not used in linear elasticity).
456+ m_dir: ti.Matrix
457+ The material direction (not used in linear elasticity).
458+
459+ Returns
460+ -------
461+ energy: float
462+ The computed energy.
463+ gradient: ti.Matrix
464+ The gradient of the energy with respect to the deformation gradient F.
465+
466+ Notes
467+ -------
468+ This implementation assumes small deformations and linear stress-strain relationship.
469+ It is adapted from the HOBAKv1 implementation for linear elasticity:
470+ https://github.com/theodorekim/HOBAKv1/blob/main/src/Hyperelastic/Volume/LINEAR.cpp
471+
472+ """
473+ F_hat = self .R [i_b , i_e ].transpose () @ F
474+ # E = 1/2(F_hat + F_hat.transpose()) - I
475+ eps = 0.5 * (F_hat + F_hat .transpose ())
476+ for i in ti .static (range (3 )):
477+ eps [i , i ] -= 1.0
478+ trEps = eps .trace ()
479+ energy = mu * eps .norm_sqr () + 0.5 * lam * trEps ** 2
480+ gradient = 2.0 * mu * self .R [i_b , i_e ] @ eps + lam * trEps * self .R [i_b , i_e ]
481+
482+ return energy , gradient
483+
484+ @ti .func
485+ def compute_energy_linear_corotated (self , mu , lam , J , F , actu , m_dir , i_e , i_b ):
486+ """
487+ Compute the energy for linear elasticity.
488+
489+ Parameters
490+ ----------
491+ mu: float
492+ The first Lame parameter (shear modulus).
493+ lam: float
494+ The second Lame parameter (related to volume change).
495+ J: float
496+ The determinant of the deformation gradient F.
497+ F: ti.Matrix
498+ The deformation gradient matrix.
499+ actu: ti.Matrix
500+ The activation matrix (not used in linear elasticity).
501+ m_dir: ti.Matrix
502+ The material direction (not used in linear elasticity).
503+
504+ Returns
505+ -------
506+ energy: float
507+ The computed energy.
508+
509+ Notes
510+ -------
511+ This implementation assumes small deformations and linear stress-strain relationship.
512+ It is adapted from the HOBAKv1 implementation for linear elasticity:
513+ https://github.com/theodorekim/HOBAKv1/blob/main/src/Hyperelastic/Volume/LINEAR.cpp
514+
515+ """
516+ F_hat = self .R [i_b , i_e ].transpose () @ F
517+ # E = 1/2(F_hat + F_hat.transpose()) - I
518+ eps = 0.5 * (F_hat + F_hat .transpose ())
519+ for i in ti .static (range (3 )):
520+ eps [i , i ] -= 1.0
521+ trEps = eps .trace ()
522+ energy = mu * eps .norm_sqr () + 0.5 * lam * trEps ** 2
523+
524+ return energy
525+
357526 @property
358527 def model (self ):
359528 """The name of the constitutive model ('linear' or 'stable_neohookean')."""
0 commit comments