Skip to content

Commit 7cb3248

Browse files
quaglacopybara-github
authored andcommitted
Allow separate stretching and bending yield strains for flex plasticity.
The flex `<elasticity yield="...">` attribute (and the same on `<flexcomp><elasticity>`) now takes one or two values, `yield="eps_stretch eps_bend"`. For non-interpolated 2D flexes a single value applies to both. For 3D and interpolated flexes a single value is only the stretching yield strain. Either way, existing models compile and simulate as before. API: - `mjsFlex::stressyield` is now `double[2]` (stretch, bend), and `mjModel::flex_yield` is `nflex x 2`. Both are unreleased. - New `mjModel::flex_plasticmode` (`nflex x 1`) records which modes have plastic state: bit 1 is bending, bit 2 is stretching (same encoding as `elastic2d`). - Whether a mode is plastic is decided at compile time, as for joints and tendons. A mode gets plastic state, and its bit set, only if its yield strain is positive. Stretching state comes first, then bending state. For example, `yield="0.01 0"` keeps bending purely elastic, and its yield strain is never read at runtime. - Setting the yield strain of a plastic mode to 0 at runtime still means full plastic flow, as before. - A positive bending yield strain on a 3D or interpolated flex is a compile error ("bending yield requires a non-interpolated 2d flex"). 1D flexes still reject any positive value. Why a new field: whether bending state exists could already be inferred (the 2D shell thickness is stored in `stiffness[6]` only when bending yields). Nothing in the model indicated whether stretching state exists. A per-flex bitmask was the smallest addition that makes both blocks and their offsets explicit. It also replaces the per-mode layout formulas that were duplicated in `mj_resetPlastic`, model validation, and `mj_printModel` (which would otherwise read past a flex's state). XML: - `yield` is `double[1..2]` with `reading=custom` in mjcf.schema. - For `<flex>` the reader resolves a single value from `dim` and `node`. For `<flexcomp>` it is resolved in `Make()`, once dim and dof are final (dim can come from a mesh or gmsh file). - The writer saves a single value when it reproduces the bending yield strain, and two values otherwise. Engine, C and MJWarp: the return mapping and the passive forces locate stretching and bending state by `flex_plasticmode`, not by the yield value. In MJWarp, `flex_yield` is `wp.vec2` and `flex_plasticmode` is threaded into the plastic and flex passive kernels. MJX warp shims were regenerated. Compiler: `mjCFlex::PlasticStretchNum()` gives the size of the stretching block of a compiled or uncompiled flex. `PlasticNum()` and keyframe scaling in a scaled frame (`ScaleKeyframe`) both use it, so a bend-only shell scales all of its entries as bending entries. Generated files regenerated: XML tables/xsd/dmcontrol schema, references.h, introspect structs.py, wasm and Unity bindings, mjx/warp, and golden flex_model.data (only `flex_yield` gains a column and `flex_plasticmode` is added). dm_control's MjModel indexer gains the new field. Tests: - XML reader: 1 vs 2 values on 2D and 3D, on flexcomp and deformable flex; single values on 3D and interpolated flexes resolve to stretching only. Errors for 3 values, a negative bending yield strain, a bending yield strain on 3D, interpolated, and 1D flexes. - XML writer: round trip with 1 and 2 values, 2D and 3D. - Engine: - stretch-only and bend-only yielding are independent; - a mode with a zero yield strain has no state and stays elastic even if its yield strain is changed at runtime; - a runtime yield strain of 0 on a plastic mode gives full plastic flow; - absent modes allocate no state. - Keyframe scaling: a bend-only shell in a scaled frame, followed by another plastic flex or last. - Model validation of `flex_plasticmode`. - MJWarp: C-vs-MJWarp parity for separate yields, per-mode allocation, and runtime-zero full flow. PiperOrigin-RevId: 1013971100 Change-Id: I26055b2b73b4e673119f0f28cfe4e757a128a38c
1 parent 57d9b96 commit 7cb3248

39 files changed

Lines changed: 672 additions & 115 deletions

‎doc/XMLreference.rst‎

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3995,7 +3995,9 @@ element is used to adjust the properties of all edges in the flex.
39953995

39963996
|body/flexcomp/elasticity attrib list|
39973997
Same as in :ref:`flex/elasticity<flex-elasticity>`.
3998-
All attributes are passed through to the automatically-generated flex.
3998+
All attributes are passed through to the automatically-generated flex. In particular, :at:`yield` takes one or two
3999+
values, for stretching and bending; a single value is also the bending yield strain only if the generated flex is a
4000+
non-interpolated 2D flex.
39994001

40004002
.. _flexcomp-pin:
40014003

@@ -4664,22 +4666,31 @@ except for 1D flexes with zero :ref:`damping<flex-elasticity-damping>`.
46644666

46654667
.. _flex-elasticity-yield:
46664668

4667-
:at:`yield`: :at-val:`real(1), "0"`
4668-
Dimensionless plastic yield strain threshold :math:`\varepsilon_y` for 2D and 3D flexes. If zero, the flex is purely
4669-
elastic. If positive, each element's (or interpolated cell's/face's) elastic stretching strain tensor is bounded by
4670-
the von Mises (:math:`J_2`) yield criterion (3D isochoric in 3D, plane-stress with out-of-plane thinning in tension
4671-
in 2D) via radial return mapping, and for non-interpolated 2D shells with bending enabled
4672-
(:ref:`elastic2d<flex-elasticity-elastic2d>` **bend** or **both**), each interior hinge's outer-fiber bending strain
4673-
:math:`\frac{t}{2} |\Delta\kappa_e| \le \varepsilon_y` is bounded via return mapping in dihedral angle space
4674-
(assuming an initially flat rest configuration). In ``mjData.plastic`` at ``flex_plasticadr[f]``, a non-interpolated
4675-
flex stores its stretching plastic metric offsets first (``3 * elemnum`` entries in 2D or ``6 * elemnum`` entries in
4676-
3D when stretching is active), followed by ``edgenum`` bending plastic entries in 2D when bending is active. An
4669+
:at:`yield`: :at-val:`real(1 or 2), "0"`
4670+
Dimensionless plastic yield strain thresholds :math:`\varepsilon_y` for stretching and bending of 2D and 3D flexes.
4671+
For non-interpolated 2D flexes, a single value applies to both, e.g., ``yield="0.01"`` is equivalent to
4672+
``yield="0.01 0.01"``; for other flexes, a single value is the stretching threshold. A mode (stretching or bending)
4673+
is plastic if its threshold is positive at compile time; its plastic state is then allocated in ``mjData.plastic``
4674+
and the bit of the mode is set in ``mjModel.flex_plasticmode[f]`` (1: bending, 2: stretching). A mode whose threshold
4675+
is zero has no plastic state and remains purely elastic, e.g., ``yield="0.01 0"`` makes only stretching plastic. As
4676+
for joints and tendons, setting the threshold of a plastic mode to zero at runtime in ``mjModel.flex_yield`` (which
4677+
has two columns) corresponds to zero yield strain (full plastic flow). If the stretching (first) threshold is
4678+
positive, each element's (or interpolated cell's/face's) elastic stretching strain tensor is bounded by the von Mises
4679+
(:math:`J_2`) yield criterion (3D isochoric in 3D, plane-stress with out-of-plane thinning in tension in 2D) via
4680+
radial return mapping. If the bending (second) threshold is positive, which requires a non-interpolated 2D flex (a
4681+
compiler error otherwise), for shells with bending enabled (:ref:`elastic2d<flex-elasticity-elastic2d>` **bend** or
4682+
**both**), each interior hinge's outer-fiber bending strain :math:`\frac{t}{2} |\Delta\kappa_e| \le \varepsilon_y` is
4683+
bounded via return mapping in dihedral angle space (assuming an initially flat rest configuration). For example,
4684+
``yield="0 0.001"`` makes a shell yield in bending while its stretching remains elastic. 1D flexes do not support
4685+
plasticity (both values must be zero). In ``mjData.plastic`` at ``flex_plasticadr[f]``, a non-interpolated flex
4686+
stores its stretching plastic metric offsets first (``3 * elemnum`` entries in 2D or ``6 * elemnum`` entries in 3D
4687+
when stretching is plastic), followed by ``edgenum`` bending plastic entries in 2D when bending is plastic. An
46774688
interpolated flex with :ref:`cellcount<body-flexcomp-cellcount>` :math:`(c_x, c_y, c_z)` stores one dimensionless
46784689
plastic stretching strain per grid cell (``6 * cx * cy * cz`` entries in 3D) or per outer grid face in 2D shell mode
46794690
(``3 * 2 * (cy*cz + cx*cz + cx*cy)`` entries); the elastic strain is measured in the corotated frame of the polar
46804691
decomposition of the physical deformation gradient :math:`J_e = \partial x / \partial X`. Bending plasticity is not
4681-
supported for interpolated flexes: with :ref:`elastic2d<flex-elasticity-elastic2d>` **bend**, :at:`yield` is
4682-
ignored and the flex remains purely elastic.
4692+
supported for interpolated flexes: with :ref:`elastic2d<flex-elasticity-elastic2d>` **bend**, :at:`yield` is ignored
4693+
and the flex remains purely elastic.
46834694

46844695
.. _flex-elasticity-elastic2d:
46854696

‎doc/changelog.rst‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ Significant new features
3535
- Ideal elasto-plasticity for joint (:ref:`springyield<body-joint-springyield>`) and tendon
3636
(:ref:`spatial<tendon-spatial-springyield>`, :ref:`fixed<tendon-fixed-springyield>`) springs (left).
3737
- Continuum elasto-plasticity (:ref:`yield<flex-elasticity-yield>`) for 2D and 3D :ref:`flexes<deformable-flex>`,
38-
with volumetric-deviatoric (von Mises :math:`J_2`) stretching and 2D shell bending return mapping (right).
38+
with separate stretching and bending yield strains for 2D shells, volumetric-deviatoric (von Mises :math:`J_2`)
39+
stretching and 2D shell bending return mapping (right).
3940

4041
.. image:: https://www.gstatic.com/mujoco/doc/images/changelog/wire.gif
4142
:align: left

‎doc/includes/references.h‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,7 @@ typedef struct mjModel_ {
944944
int* flex_elemedgeadr; // first element edge id address (nflex x 1)
945945
int* flex_bendingadr; // first bending data address (nflex x 1)
946946
int* flex_plasticadr; // plastic state address; -1: elastic (nflex x 1)
947+
int* flex_plasticmode; // plastic state bits; 1: bend, 2: stretch (nflex x 1)
947948
int* flex_shellnum; // number of shells (nflex x 1)
948949
int* flex_shelldataadr; // first shell data address (nflex x 1)
949950
int* flex_texcoordadr; // address in flex_texcoord; -1: none (nflex x 1)
@@ -974,7 +975,7 @@ typedef struct mjModel_ {
974975
mjtNum* efm0_L; // factor of M + (dt^2+dt*d)*K_bend (nefm0L x 1)
975976
int* efmC_perm; // sparse factor order: vertex dof or -1 (nefmCvert x 1)
976977
mjtNum* flex_damping; // Rayleigh's damping coefficient (nflex x 1)
977-
mjtNum* flex_yield; // yield strain threshold; 0: elastic (nflex x 1)
978+
mjtNum* flex_yield; // yield strain (stretch, bend); 0: elastic (nflex x 2)
978979
mjtNum* flex_edgestiffness; // edge stiffness (nflex x 1)
979980
mjtNum* flex_edgedamping; // edge damping (nflex x 1)
980981
int* flex_edgeequality; // 0:none, 1:edges, 3:strain (nflex x 1)
@@ -2147,7 +2148,7 @@ typedef struct mjsFlex_ { // flex specification
21472148
double shear; // 1D torsion shear modulus; 0: young / (2 (1 + poisson))
21482149
double damping; // Rayleigh's damping
21492150
double thickness; // thickness (2D only)
2150-
double stressyield; // yield strain threshold; 0: elastic
2151+
double stressyield[2]; // yield strain thresholds (stretch, bend); 0: elastic
21512152
int elastic2d; // 2D passive forces; 0: none, 1: bending, 2: stretching, 3: both
21522153
int elastic3d; // experimental 3D material (mjSpec only); 0: Saint
21532154
// Venant-Kirchhoff, 1: Stable Neo-Hookean

‎include/mujoco/mjmodel.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ typedef struct mjModel_ {
574574
int* flex_elemedgeadr; // first element edge id address (nflex x 1)
575575
int* flex_bendingadr; // first bending data address (nflex x 1)
576576
int* flex_plasticadr; // plastic state address; -1: elastic (nflex x 1)
577+
int* flex_plasticmode; // plastic state bits; 1: bend, 2: stretch (nflex x 1)
577578
int* flex_shellnum; // number of shells (nflex x 1)
578579
int* flex_shelldataadr; // first shell data address (nflex x 1)
579580
int* flex_texcoordadr; // address in flex_texcoord; -1: none (nflex x 1)
@@ -604,7 +605,7 @@ typedef struct mjModel_ {
604605
mjtNum* efm0_L; // factor of M + (dt^2+dt*d)*K_bend (nefm0L x 1)
605606
int* efmC_perm; // sparse factor order: vertex dof or -1 (nefmCvert x 1)
606607
mjtNum* flex_damping; // Rayleigh's damping coefficient (nflex x 1)
607-
mjtNum* flex_yield; // yield strain threshold; 0: elastic (nflex x 1)
608+
mjtNum* flex_yield; // yield strain (stretch, bend); 0: elastic (nflex x 2)
608609
mjtNum* flex_edgestiffness; // edge stiffness (nflex x 1)
609610
mjtNum* flex_edgedamping; // edge damping (nflex x 1)
610611
int* flex_edgeequality; // 0:none, 1:edges, 3:strain (nflex x 1)

‎include/mujoco/mjspec.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ typedef struct mjsFlex_ { // flex specification
554554
double shear; // 1D torsion shear modulus; 0: young / (2 (1 + poisson))
555555
double damping; // Rayleigh's damping
556556
double thickness; // thickness (2D only)
557-
double stressyield; // yield strain threshold; 0: elastic
557+
double stressyield[2]; // yield strain thresholds (stretch, bend); 0: elastic
558558
int elastic2d; // 2D passive forces; 0: none, 1: bending, 2: stretching, 3: both
559559
int elastic3d; // experimental 3D material (mjSpec only); 0: Saint
560560
// Venant-Kirchhoff, 1: Stable Neo-Hookean

‎include/mujoco/mjspecmacro.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@
306306
X ( double, shear, 1 ) \
307307
X ( double, damping, 1 ) \
308308
X ( double, thickness, 1 ) \
309-
X ( double, stressyield, 1 ) \
309+
XVEC( double, stressyield, 2 ) \
310310
X ( int, elastic2d, 1 ) \
311311
X ( int, elastic3d, 1 ) \
312312
X ( mjtFlexSection, section, 1 ) \

‎include/mujoco/mjxmacro.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@
482482
X ( int, flex_elemedgeadr, nflex, 1 ) \
483483
X ( int, flex_bendingadr, nflex, 1 ) \
484484
X ( int, flex_plasticadr, nflex, 1 ) \
485+
X ( int, flex_plasticmode, nflex, 1 ) \
485486
X ( int, flex_shellnum, nflex, 1 ) \
486487
X ( int, flex_shelldataadr, nflex, 1 ) \
487488
X ( int, flex_texcoordadr, nflex, 1 ) \
@@ -512,7 +513,7 @@
512513
X ( mjtNum, efm0_L, nefm0L, 1 ) \
513514
X ( int, efmC_perm, nefmCvert, 1 ) \
514515
X ( mjtNum, flex_damping, nflex, 1 ) \
515-
X ( mjtNum, flex_yield, nflex, 1 ) \
516+
X ( mjtNum, flex_yield, nflex, 2 ) \
516517
X ( mjtNum, flex_edgestiffness, nflex, 1 ) \
517518
X ( mjtNum, flex_edgedamping, nflex, 1 ) \
518519
X ( int, flex_edgeequality, nflex, 1 ) \

‎mjx/mujoco/mjx/third_party/mujoco_warp/_src/forward.py‎

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -741,12 +741,13 @@ def _next_plastic_flex_stretch(
741741
flex_stiffnessadr: wp.array[int],
742742
flex_elemedgeadr: wp.array[int],
743743
flex_plasticadr: wp.array[int],
744+
flex_plasticmode: wp.array[int],
744745
flex_vertbodyid: wp.array[int],
745746
flex_elem: wp.array[int],
746747
flex_elemedge: wp.array[int],
747748
flexedge_length0: wp.array[float],
748749
flex_stiffness: wp.array[float],
749-
flex_yield: wp.array[float],
750+
flex_yield: wp.array[wp.vec2],
750751
flex_elemflexid: wp.array[int],
751752
# Data in:
752753
qvel_in: wp.array2d[float],
@@ -764,9 +765,9 @@ def _next_plastic_flex_stretch(
764765
padr_base = flex_plasticadr[f]
765766
if padr_base < 0:
766767
return
767-
yield_ = wp.max(0.0, flex_yield[f])
768+
yield_ = wp.max(0.0, flex_yield[f][0])
768769
dim = flex_dim[f]
769-
if (dim != 2 and dim != 3) or flex_interp[f] != 0:
770+
if (dim != 2 and dim != 3) or flex_interp[f] != 0 or (flex_plasticmode[f] & 2) == 0:
770771
return
771772
stiffness_adr_base = flex_stiffnessadr[f]
772773
if stiffness_adr_base < 0 or flex_stiffness[stiffness_adr_base] == 0.0:
@@ -912,13 +913,14 @@ def _next_plastic_flex_bend(
912913
flex_stiffnessadr: wp.array[int],
913914
flex_bendingadr: wp.array[int],
914915
flex_plasticadr: wp.array[int],
916+
flex_plasticmode: wp.array[int],
915917
flex_vertbodyid: wp.array[int],
916918
flex_edge: wp.array[wp.vec2i],
917919
flex_edgeflap: wp.array[wp.vec2i],
918920
flexedge_length0: wp.array[float],
919921
flex_stiffness: wp.array[float],
920922
flex_bending: wp.array[float],
921-
flex_yield: wp.array[float],
923+
flex_yield: wp.array[wp.vec2],
922924
flex_edgeflexid: wp.array[int],
923925
# Data in:
924926
qvel_in: wp.array2d[float],
@@ -935,7 +937,7 @@ def _next_plastic_flex_bend(
935937
padr_base = flex_plasticadr[f]
936938
if padr_base < 0:
937939
return
938-
if flex_dim[f] != 2 or flex_interp[f] != 0:
940+
if flex_dim[f] != 2 or flex_interp[f] != 0 or (flex_plasticmode[f] & 1) == 0:
939941
return
940942
bending_adr_base = flex_bendingadr[f]
941943
stiffness_adr_base = flex_stiffnessadr[f]
@@ -1000,13 +1002,13 @@ def _next_plastic_flex_bend(
10001002
if denom <= MJ_MINVAL or l0 <= MJ_MINVAL:
10011003
return
10021004

1003-
yield_ = wp.max(0.0, flex_yield[f])
1005+
yield_ = wp.max(0.0, flex_yield[f][1])
10041006
kappa_yield = 2.0 * yield_ / thickness
10051007
omega = wp.dot(ed2, frc3)
10061008
theta = wp.atan2(omega * l0, wp.dot(frc2, frc3))
10071009
theta_yield = 0.5 * (two_a1 + two_a2) / l0 * kappa_yield
10081010

1009-
stretch_pnum = 3 * flex_elemnum[f] if flex_stiffness[stiffness_adr_base] != 0.0 else 0
1011+
stretch_pnum = 3 * flex_elemnum[f] if (flex_plasticmode[f] & 2) != 0 else 0
10101012
padr = padr_base + stretch_pnum + eid
10111013
b16_0 = flex_bending[bbase + 16]
10121014
b_p = plastic_in[worldid, padr]
@@ -1037,7 +1039,7 @@ def _next_plastic_flex_interp(
10371039
flex_nodebodyid: wp.array[int],
10381040
flex_node0: wp.array[wp.vec3],
10391041
flex_stiffness: wp.array[float],
1040-
flex_yield: wp.array[float],
1042+
flex_yield: wp.array[wp.vec2],
10411043
flex_faceadr: wp.array[int],
10421044
flex_cell_map: wp.array[wp.vec4i],
10431045
flex_face: wp.array2d[int],
@@ -1152,7 +1154,7 @@ def _next_plastic_flex_interp(
11521154
f1 += xpos_j * (phi_x * dphi_y * phi_z)
11531155
f2 += xpos_j * (phi_x * phi_y * dphi_z)
11541156

1155-
yield_ = wp.max(0.0, flex_yield[f])
1157+
yield_ = wp.max(0.0, flex_yield[f][0])
11561158
if shell_mode:
11571159
normal_axis = 0 if ci < 2 * cy * cz else (1 if ci < 2 * (cy * cz + cx * cz) else 2)
11581160
axis0 = (normal_axis + 1) % 3
@@ -1417,6 +1419,7 @@ def _advance(m: Model, d: Data, qacc: wp.array, qvel: Optional[wp.array] = None)
14171419
m.flex_stiffnessadr,
14181420
m.flex_elemedgeadr,
14191421
m.flex_plasticadr,
1422+
m.flex_plasticmode,
14201423
m.flex_vertbodyid,
14211424
m.flex_elem,
14221425
m.flex_elemedge,
@@ -1453,6 +1456,7 @@ def _advance(m: Model, d: Data, qacc: wp.array, qvel: Optional[wp.array] = None)
14531456
m.flex_stiffnessadr,
14541457
m.flex_bendingadr,
14551458
m.flex_plasticadr,
1459+
m.flex_plasticmode,
14561460
m.flex_vertbodyid,
14571461
m.flex_edge,
14581462
m.flex_edgeflap,

‎mjx/mujoco/mjx/third_party/mujoco_warp/_src/io.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,8 @@ def _check_friction(name: str, id_: int, condim: int, friction, checks):
596596
m.tendon_plasticadr = np.full(mjm.ntendon, -1, dtype=np.int32)
597597
if not hasattr(mjm, "flex_plasticadr"):
598598
m.flex_plasticadr = np.full(mjm.nflex, -1, dtype=np.int32)
599+
if not hasattr(mjm, "flex_plasticmode"):
600+
m.flex_plasticmode = np.zeros(mjm.nflex, dtype=np.int32)
599601

600602
m.opt = opt
601603
m.callback = types.Callback()

‎mjx/mujoco/mjx/third_party/mujoco_warp/_src/passive.py‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2652,6 +2652,7 @@ def kernel(
26522652
flex_stiffnessadr: wp.array[int],
26532653
flex_elemedgeadr: wp.array[int],
26542654
flex_plasticadr: wp.array[int],
2655+
flex_plasticmode: wp.array[int],
26552656
flex_edge: wp.array[wp.vec2i],
26562657
flex_elem: wp.array[int],
26572658
flex_elemedge: wp.array[int],
@@ -2693,7 +2694,7 @@ def kernel(
26932694
ee_base = flex_elemedgeadr[f] + local_elemid * nedge
26942695
stiffness_adr = flex_stiffnessadr[f] + local_elemid * (FLEX_STIFFNESS_3D if dim == 3 else 21)
26952696
snh = wp.static(FLEX_STIFFNESS_3D == 24) and dim == 3 and flex_stiffness[stiffness_adr + 21] != 0.0
2696-
padr = flex_plasticadr[f] + local_elemid * nedge if flex_plasticadr[f] >= 0 else -1
2697+
padr = flex_plasticadr[f] + local_elemid * nedge if (flex_plasticmode[f] & 2) != 0 else -1
26972698

26982699
elem_verts = wp.vec4i(-1, -1, -1, -1)
26992700
vert_xpos = mat43()
@@ -2866,6 +2867,7 @@ def flex_hessian(m: Model, d: Data):
28662867
m.flex_stiffnessadr,
28672868
m.flex_elemedgeadr,
28682869
m.flex_plasticadr,
2870+
m.flex_plasticmode,
28692871
m.flex_edge,
28702872
m.flex_elem,
28712873
m.flex_elemedge,
@@ -3594,6 +3596,7 @@ def kernel(
35943596
flex_stiffnessadr: wp.array[int],
35953597
flex_elemedgeadr: wp.array[int],
35963598
flex_plasticadr: wp.array[int],
3599+
flex_plasticmode: wp.array[int],
35973600
flex_vertbodyid: wp.array[int],
35983601
flex_elem: wp.array[int],
35993602
flex_elemedge: wp.array[int],
@@ -3668,7 +3671,7 @@ def kernel(
36683671

36693672
elemedge_adr = flex_elemedgeadr[f] + local_elemid * nedge
36703673
edge_adr = flex_edgeadr[f]
3671-
padr = flex_plasticadr[f] + local_elemid * nedge if flex_plasticadr[f] >= 0 else -1
3674+
padr = flex_plasticadr[f] + local_elemid * nedge if (flex_plasticmode[f] & 2) != 0 else -1
36723675

36733676
elongation_spring = vec6(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
36743677
if not dsbl_spring:
@@ -4045,6 +4048,7 @@ def kernel(
40454048
flex_stiffnessadr: wp.array[int],
40464049
flex_bendingadr: wp.array[int],
40474050
flex_plasticadr: wp.array[int],
4051+
flex_plasticmode: wp.array[int],
40484052
flex_vertbodyid: wp.array[int],
40494053
flex_edge: wp.array[wp.vec2i],
40504054
flex_edgeflap: wp.array[wp.vec2i],
@@ -4110,9 +4114,8 @@ def kernel(
41104114
bbase = bendingadr + 17 * eid
41114115
c16 = flex_bending[bbase + 16]
41124116
padr_base = flex_plasticadr[f]
4113-
if padr_base >= 0:
4114-
stiffness_adr = flex_stiffnessadr[f]
4115-
stretch_pnum = 3 * flex_elemnum[f] if (stiffness_adr >= 0 and flex_stiffness[stiffness_adr] != 0.0) else 0
4117+
if (flex_plasticmode[f] & 1) != 0:
4118+
stretch_pnum = 3 * flex_elemnum[f] if (flex_plasticmode[f] & 2) != 0 else 0
41164119
c16 += plastic_in[worldid, padr_base + stretch_pnum + eid]
41174120
frc = mat43()
41184121
if has_spring and c16 != 0.0:
@@ -5318,6 +5321,7 @@ def passive(m: Model, d: Data):
53185321
m.flex_stiffnessadr,
53195322
m.flex_elemedgeadr,
53205323
m.flex_plasticadr,
5324+
m.flex_plasticmode,
53215325
m.flex_vertbodyid,
53225326
m.flex_elem,
53235327
m.flex_elemedge,
@@ -5354,6 +5358,7 @@ def passive(m: Model, d: Data):
53545358
m.flex_stiffnessadr,
53555359
m.flex_bendingadr,
53565360
m.flex_plasticadr,
5361+
m.flex_plasticmode,
53575362
m.flex_vertbodyid,
53585363
m.flex_edge,
53595364
m.flex_edgeflap,

0 commit comments

Comments
 (0)
⌂ 换网址