📃 命名与变量#
不同的求解器使用各种格式表示物理实体,例如粒子、单元、网格和表面。每个数据字段都根据其对应的表示方式进行前缀标记。为了计算效率和结构,与不同物理属性相关的数据字段被组织成以下类别(基于计算类型):
*_state_*:在每个求解器步骤中更新的动态状态。这些字段默认启用requires_grad实例化。其字段大小为:如果可微分,则是(子步数,单元数);如果不可微分,则是(单元数),其中单元取决于表示方式,如粒子、顶点等。可能有不同的后缀用于进一步指定,例如:*_state_ng:将requires_gradient设置为 False。
*_info:在整个模拟过程中保持不变的静态属性,通常涵盖物理属性,如质量、刚度、粘度等。其字段大小为(单元数,)*_render:仅用于可视化的字段,不直接参与物理计算。其字段大小为(单元数,)。
总体而言,命名遵循 <representation>_<computation-type>。(我们始终使用复数形式,例如 dofs、particles、elements 等。)
此外,一些有用的通用数据类型(定义在 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 获取更多详情。