📃 命名与变量#

不同的求解器使用各种格式表示物理实体,例如粒子、单元、网格和表面。每个数据字段都根据其对应的表示方式进行前缀标记。为了计算效率和结构,与不同物理属性相关的数据字段被组织成以下类别(基于计算类型):

  • *_state_*:在每个求解器步骤中更新的动态状态。这些字段默认启用 requires_grad 实例化。其字段大小为:如果可微分,则是(子步数,单元数);如果不可微分,则是(单元数),其中单元取决于表示方式,如粒子、顶点等。可能有不同的后缀用于进一步指定,例如:

    • *_state_ng:将 requires_gradient 设置为 False。

  • *_info:在整个模拟过程中保持不变的静态属性,通常涵盖物理属性,如质量、刚度、粘度等。其字段大小为(单元数,)

  • *_render:仅用于可视化的字段,不直接参与物理计算。其字段大小为(单元数,)。

总体而言,命名遵循 <representation>_<computation-type>。(我们始终使用复数形式,例如 dofsparticleselements 等。)

此外,一些有用的通用数据类型(定义在 genesis/__init__.py):

ti_vec2 = ti.types.vector(2, ti_float)
ti_vec3 = ti.types.vector(3, ti_float)
ti_vec4 = ti.types.vector(4, ti_float)
ti_vec6 = ti.types.vector(6, ti_float)
ti_vec7 = ti.types.vector(7, ti_float)
ti_vec11 = ti.types.vector(11, ti_float)

ti_mat3 = ti.types.matrix(3, 3, ti_float)
ti_mat4 = ti.types.matrix(4, 4, ti_float)

ti_ivec2 = ti.types.vector(2, ti_int)
ti_ivec3 = ti.types.vector(3, ti_int)
ti_ivec4 = ti.types.vector(4, ti_int)

在以下章节中,我们简要描述每个求解器使用的变量。

刚体求解器 (Rigid Solver)#

刚体求解器涉及连杆、关节、几何体和顶点表示。刚体求解器模拟由连杆和关节组成的关节体,每个连杆可能由多个几何组件组成。每个几何体又可能包含多个顶点。

对于连杆 (links):

  • 动态连杆状态 (links_state)

    ti.types.struct(
        parent_idx=gs.ti_int,         # 运动树中父连杆的索引(如果是根则为 -1)
        root_idx=gs.ti_int,           # 关节中根连杆的索引
        q_start=gs.ti_int,            # 全局配置向量 (q) 中的起始索引
        dof_start=gs.ti_int,          # 全局自由度向量中的起始索引
        joint_start=gs.ti_int,        # 影响此连杆的关节的起始索引
        q_end=gs.ti_int,              # 全局配置向量中的结束索引
        dof_end=gs.ti_int,            # 全局自由度向量中的结束索引
        joint_end=gs.ti_int,          # 影响此连杆的关节的结束索引
        n_dofs=gs.ti_int,             # 此连杆的自由度数量
        pos=gs.ti_vec3,               # 连杆当前的世界空间位置
        quat=gs.ti_vec4,              # 连杆当前的世界空间方向(四元数)
        invweight=gs.ti_vec2,         # 逆质量
        is_fixed=gs.ti_int,           # 布尔标志:如果连杆固定/静态则为 1,动态则为 0
        inertial_pos=gs.ti_vec3,      # 惯性坐标系(质心)在连杆局部坐标中的位置
        inertial_quat=gs.ti_vec4,     # 惯性坐标系相对于连杆坐标系的方向
        inertial_i=gs.ti_mat3,        # 惯性坐标系中的惯性张量
        inertial_mass=gs.ti_float,    # 连杆的质量
        entity_idx=gs.ti_int,         # 此连杆所属实体的索引
    )
    
  • 静态连杆信息 (links_info)

    ti.types.struct(
        cinr_inertial=gs.ti_mat3,     # 基于质心的体惯性
        cinr_pos=gs.ti_vec3,          # 基于质心的体位置
        cinr_quat=gs.ti_vec4,         # 基于质心的体方向
        cinr_mass=gs.ti_float,        # 基于质心的体质量
        crb_inertial=gs.ti_mat3,      # 基于质心的复合惯性
        crb_pos=gs.ti_vec3,           # 基于质心的复合位置
        crb_quat=gs.ti_vec4,          # 基于质心的复合方向
        crb_mass=gs.ti_float,         # 基于质心的复合质量
        cdd_vel=gs.ti_vec3,           # 基于质心的加速度(线性)
        cdd_ang=gs.ti_vec3,           # 基于质心的加速度(角)
        pos=gs.ti_vec3,               # 当前世界位置
        quat=gs.ti_vec4,              # 当前方向
        ang=gs.ti_vec3,               # 角速度
        vel=gs.ti_vec3,               # 线速度
        i_pos=gs.ti_vec3,             # 惯性位置
        i_quat=gs.ti_vec4,            # 惯性方向
        j_pos=gs.ti_vec3,             # 关节坐标系位置
        j_quat=gs.ti_vec4,            # 关节坐标系方向
        j_vel=gs.ti_vec3,             # 关节线速度
        j_ang=gs.ti_vec3,             # 关节角速度
        cd_ang=gs.ti_vec3,            # 基于质心的速度(角)
        cd_vel=gs.ti_vec3,            # 基于质心的速度(线性)
        root_COM=gs.ti_vec3,          # 根连杆子树的质心
        mass_sum=gs.ti_float,         # 以此连杆为根的子树的总质量
        mass_shift=gs.ti_float,       # 质量偏移
        i_pos_shift=gs.ti_vec3,       # 惯性位置偏移
        cfrc_flat_ang=gs.ti_vec3,     # 基于质心的相互作用力(角)
        cfrc_flat_vel=gs.ti_vec3,     # 基于质心的相互作用力(线性)
        cfrc_ext_ang=gs.ti_vec3,      # 基于质心的外力(角)
        cfrc_ext_vel=gs.ti_vec3,      # 基于质心的外力(线性)
        contact_force=gs.ti_vec3,     # 来自环境的净接触力
        hibernated=gs.ti_int,         # 如果连杆处于休眠/静态状态则为 1
    )
    

对于关节 (joints):

  • 动态自由度状态 (dofs_state)

    ti.types.struct(
        force=gs.ti_float,            # 累积后应用于此自由度的总净力
        qf_bias=gs.ti_float,          # 
        qf_passive=gs.ti_float,       # 总被动力
        qf_actuator=gs.ti_float,      # 执行器力
        qf_applied=gs.ti_float,       # 
        act_length=gs.ti_float,       # 
        pos=gs.ti_float,              # 位置
        vel=gs.ti_float,              # 速度
        acc=gs.ti_float,              # 加速度
        acc_smooth=gs.ti_float,       # 
        qf_smooth=gs.ti_float,        # 
        qf_constraint=gs.ti_float,    # 约束力
        cdof_ang=gs.ti_vec3,          # 基于质心的运动轴(角)
        cdof_vel=gs.ti_vec3,          # 基于质心的运动轴(线性)
        cdofvel_ang=gs.ti_vec3,       # 
        cdofvel_vel=gs.ti_vec3,       # 
        cdofd_ang=gs.ti_vec3,         # cdof 的时间导数(角)
        cdofd_vel=gs.ti_vec3,         # cdof 的时间导数(线性)
        f_vel=gs.ti_vec3,             # 
        f_ang=gs.ti_vec3,             # 
        ctrl_force=gs.ti_float,       # 控制器的目标力
        ctrl_pos=gs.ti_float,         # 控制器的目标位置
        ctrl_vel=gs.ti_float,         # 控制器的目标速度
        ctrl_mode=gs.ti_int,          # 控制模式(例如位置、速度、扭矩)
        hibernated=gs.ti_int,         # 指示休眠状态
    )
    
  • 静态自由度信息 (dofs_info)

    ti.types.struct(
        stiffness=gs.ti_float,        # 自由度的刚度
        sol_params=gs.ti_vec7,        # 约束求解器 ()
        invweight=gs.ti_float,        # 逆质量
        armature=gs.ti_float,         # 自由度电枢惯性/质量 
        damping=gs.ti_float,          # 阻尼系数
        motion_ang=gs.ti_vec3,        # 规定的角运动目标
        motion_vel=gs.ti_vec3,        # 规定的线运动目标
        limit=gs.ti_vec2,             # 自由度的位置下限和上限
        dof_start=gs.ti_int,          # 自由度在全局系统中的起始索引
        kp=gs.ti_float,               # PD 控制的比例增益
        kv=gs.ti_float,               # PD 控制的微分增益
        force_range=gs.ti_vec2,       # 允许的最小和最大控制力
    )
    
  • 静态关节信息 (joints_info)

    ti.types.struct(
        type=gs.ti_int,               # 关节类型 ID(例如旋转、平移、固定)
        sol_params=gs.ti_vec7,        # 约束求解器(参考;阻抗)
        q_start=gs.ti_int,            # 全局配置向量 (q) 中的起始索引
        dof_start=gs.ti_int,          # 全局自由度向量中的起始索引
        q_end=gs.ti_int,              # 全局配置向量中的结束索引
        dof_end=gs.ti_int,            # 全局自由度向量中的结束索引
        n_dofs=gs.ti_int,             # 此关节的自由度数量
        pos=gs.ti_vec3,               # 关节在世界空间中的位置
    )
    

对于几何体 (geometries):

  • 动态几何体状态 (geom_state)

    ti.types.struct(
        pos=gs.ti_vec3,               # 几何体的当前世界位置
        quat=gs.ti_vec4,              # 几何体的当前世界方向(四元数)
        vel=gs.ti_vec3,               # 几何体的线速度
        ang=gs.ti_vec3,               # 几何体的角速度
        aabb_min=gs.ti_vec3,          # 几何体 AABB(轴对齐边界框)的最小边界
        aabb_max=gs.ti_vec3,          # 几何体 AABB 的最大边界
    )
    
  • 静态几何体信息 (geom_info)

    ti.types.struct(
        link_idx=gs.ti_int,           # 此几何体所属连杆的索引
        type=gs.ti_int,               # 几何体类型(例如盒体、球体、网格)
        local_pos=gs.ti_vec3,         # 连杆局部坐标系中的位置
        local_quat=gs.ti_vec4,        # 连杆局部坐标系中的方向
        size=gs.ti_vec3,              # 尺寸或包围体
    )
    

MPM 求解器 (MPM Solver)#

物质点法 (MPM) 使用粒子和网格表示。

对于粒子 (particles):

  • 动态粒子状态 (particles_state)

    ti.types.struct(
        pos=gs.ti_vec3,    # 位置
        vel=gs.ti_vec3,    # 速度
        C=gs.ti_mat3,      # 仿射速度场
        F=gs.ti_mat3,      # 变形梯度
        F_tmp=gs.ti_mat3,  # 临时变形梯度
        U=gs.ti_mat3,      # SVD(奇异值分解)中的左正交矩阵
        V=gs.ti_mat3,      # SVD 中的右正交矩阵
        S=gs.ti_mat3,      # SVD 中的对角矩阵
        actu=gs.ti_float,  # 驱动
        Jp=gs.ti_float,    # 体积比
    )
    
  • 无梯度的动态粒子状态 (particles_stage_ng)

    ti.types.struct(
        active=gs.ti_int,  # 粒子是否激活
    )
    
  • 静态粒子信息 (particles_info)

    ti.types.struct(
        material_idx=gs.ti_int,       # 材料 id
        mass=gs.ti_float,             # 质量
        default_Jp=gs.ti_float,       # 默认体积比
        free=gs.ti_int,               # 粒子是否自由;非自由粒子表现为边界条件
        muscle_group=gs.ti_int,       # 肌肉/驱动组
        muscle_direction=gs.ti_vec3,  # 肌肉/驱动方向
    )
    

对于网格 (grid):

  • 动态网格状态 (grid_state)

    ti.types.struct(
        vel_in=gs.ti_vec3,   # 输入动量
        mass=gs.ti_float,    # 质量
        vel_out=gs.ti_vec3,  # 输出速度
    )
    

对于渲染 (rendering):

  • 基于粒子的渲染的粒子属性 (particles_render)

    ti.types.struct(
        pos=gs.ti_vec3,   # 位置
        vel=gs.ti_vec3,   # 速度
        active=gs.ti_int, # 粒子是否激活
    )
    
  • 基于视觉渲染的静态虚拟顶点信息 (vverts_info)

    ti.types.struct(
        support_idxs=ti.types.vector(n_vvert_supports, gs.ti_int),      # 支撑粒子的索引
        support_weights=ti.types.vector(n_vvert_supports, gs.ti_float), # 插值权重
    )
    
  • 基于视觉渲染的动态虚拟顶点状态 (vverts_render)

    ti.types.struct(
        pos=gs.ti_vec3,   # 虚拟顶点的位置
        active=gs.ti_int, # 虚拟顶点是否激活
    )
    

查看 genesis/solvers/mpm_solver.py 获取更多详情。

FEM 求解器 (FEM Solver)#

有限元法 (FEM) 使用单元和表面表示,其中单元中的一些属性存储在相关顶点中。

对于单元 (elements):

  • 单元中的动态单元状态 (elements_el_state)

    ti.types.struct(
        actu=gs.ti_float,  # 驱动
    )
    
  • 顶点中的动态单元状态 (elements_v_state)

    ti.types.struct(
        pos=gs.ti_vec3,  # 位置
        vel=gs.ti_vec3,  # 速度
    )
    
  • 无梯度的动态单元状态 (elements_el_state_ng)

    ti.types.struct(
        active=gs.ti_int,  # 单元是否激活
    )
    
  • 静态单元信息 (elements_el_info)

    ti.types.struct(
        el2v=gs.ti_ivec4,            # 单元的顶点索引
        mu=gs.ti_float,              # Lame 参数 (1)
        lam=gs.ti_float,             # Lame 参数 (2)
        mass_scaled=gs.ti_float,     # 缩放后的单元质量。实际质量为 mass_scaled / self._vol_scale
        material_idx=gs.ti_int,      # 材料模型索引
        B=gs.ti_mat3,                # 未变形形状矩阵的逆
        muscle_group=gs.ti_int,      # 肌肉/执行器组
        muscle_direction=gs.ti_vec3, # 肌肉/执行器方向
    )
    

对于表面 (surfaces):

  • 静态表面信息 (surfaces_info)

    ti.types.struct(
        tri2v=gs.ti_ivec3,  # 三角形的顶点索引
        tri2el=gs.ti_int,   # 三角形的单元索引
        active=gs.ti_int,   # 此表面单元是否激活
    )
    

对于渲染 (rendering):

  • 顶点中的动态表面属性 (surfaces_v_render)

    ti.types.struct(
        vertices=gs.ti_vec3, # 位置
    )
    
  • 面中的动态表面属性 (surfaces_f_render)

    ti.types.struct(
        indices=gs.ti_int, # 与此表面单元对应的顶点索引(TODO:这很丑陋,因为我们扁平化了 (n_surfaces_max, 3))
    )
    

查看 genesis/solvers/fem_solver.py 获取更多详情。

PBD 求解器 (PBD Solver)#

基于位置的动力学 (PBD) 使用基于粒子的表示。

对于粒子 (particles):

  • 动态粒子状态 (particles_state, particles_state_reordered)

    ti.types.struct(
        free=gs.ti_int,  # 粒子是否可以自由移动。如果为 0,则它是运动学控制的(例如固定或外部操纵)
        pos=gs.ti_vec3,  # 位置
        ipos=gs.ti_vec3, # 初始位置
        dpos=gs.ti_vec3, # 位置增量
        vel=gs.ti_vec3,  # 速度
        lam=gs.ti_float, # Lagrange 乘子或约束力标量
        rho=gs.ti_float, # 估计的流体密度
    )
    
  • 无梯度的动态粒子状态 (particles_state_ng, particles_state_ng_reordered)

    ti.types.struct(
        reordered_idx=gs.ti_int, # 重新排序索引
        active=gs.ti_int,        # 粒子是否激活
    )
    
  • 静态粒子信息 (particles_info, particles_info_reordered)

    ti.types.struct(
        mass=gs.ti_float,                 # 质量
        pos_rest=gs.ti_vec3,              # 静止位置
        rho_rest=gs.ti_float,             # 静止密度
        material_type=gs.ti_int,          # 材料类型
        mu_s=gs.ti_float,                 # 静摩擦系数
        mu_k=gs.ti_float,                 # 动摩擦系数
        air_resistance=gs.ti_float,       # 空气阻力/阻尼系数
        density_relaxation=gs.ti_float,   # 密度约束求解器的参数
        viscosity_relaxation=gs.ti_float, # 粘度行为的参数
    )
    

对于渲染 (rendering):

  • 粒子属性 (particles_render)

    ti.types.struct(
        pos=gs.ti_vec3,   # 位置
        vel=gs.ti_vec3,   # 速度
        active=gs.ti_int, # 粒子是否激活
    )
    

查看 genesis/solvers/pbd_solver.py 获取更多详情。

SPH 求解器 (SPH Solver)#

光滑粒子流体动力学 (SPH) 使用基于粒子的表示。

对于粒子 (particles):

  • 动态粒子状态 (particles_state, particles_state_reordered)

    ti.types.struct(
        pos=gs.ti_vec3,           # 位置
        vel=gs.ti_vec3,           # 速度
        acc=gs.ti_vec3,           # 加速度
        rho=gs.ti_float,          # 密度
        p=gs.ti_float,            # 压力
        dfsph_factor=gs.ti_float, # DFSPH 压力求解中使用的因子
        drho=gs.ti_float,         # 密度导数(变化率)
    )
    
  • 无梯度的动态粒子状态 (particles_state_ng, particles_state_ng_reordered)

    ti.types.struct(
        reordered_idx=gs.ti_int, # 重新排序索引 
        active=gs.ti_int,        # 粒子是否激活
    )
    
  • 静态粒子信息 (particles_info, particles_info_reordered)

    ti.types.struct(
        rho=gs.ti_float,       # 静止密度
        mass=gs.ti_float,      # 粒子质量
        stiffness=gs.ti_float, # 状态方程刚度
        exponent=gs.ti_float,  # 状态方程指数
        mu=gs.ti_float,        # 粘度系数
        gamma=gs.ti_float,     # 表面张力系数
    )
    

对于渲染 (rendering):

  • 粒子属性 (particles_render)

    ti.types.struct(
        pos=gs.ti_vec3,   # 位置
        vel=gs.ti_vec3,   # 速度
        active=gs.ti_int, # 粒子是否激活
    )
    

查看 genesis/solvers/sph_solver.py 获取更多详情。