这是太极实习生张铭睿同学做的SPH太极库。请看
https://www.bilibili.com/video/BV1mg411y7i9?p=10&vd_source=e15eb8f98a9dde1c9cc874314025b575
是作者的讲解。
我们来探索一下这个库。
这只是个笔记,写得会比较细碎。
除了requirements里面的安装,还要安装一些库。其中pyglet如果安装不正确版本会报错。
pyglet==1.5.27
为了调试方便,我们指定默认
由于采用了python,所以走一遍控制流是比较简单的。
先从run_simulation.py进入
然后采用argparse这个第三方库来进行命令行参数的解析。
使用json这个第三方库进行场景json文件的解析。这一步放在了SimConfig这个自定义类内。位于config_builder.py
这时命令行会打印出
{'Configuration': {'domainStart': [0.0, 0.0, 0.0], 'domainEnd': [5.0, 3.0, 2.0], 'particleRadius': 0.01, 'numberOfStepsPerRenderUpdate': 1, 'density0': 1000, 'simulationMethod': 4, 'gravitation': [0.0, -9.81, 0.0], 'timeStepSize': 0.0004, 'stiffness': 50000,
'exponent': 7, 'boundaryHandlingMethod': 0, 'exportFrame': False, 'exportPly': False, 'exportObj': False}, 'RigidBodies': [{'objectId': 1, 'geometryFile': './data/models/Dragon_50k.obj', 'translation': [3.5, 0.05, 1.0], 'rotationAxis': [0, 1, 0], 'rotationAngle': 0, 'scale': [1, 1, 1], 'velocity': [0.0, 0.0, 0.0], 'density': 1000.0, 'color': [255, 255, 255], 'isDynamic': False}], 'FluidBlocks': [{'objectId': 0, 'start': [0.1, 0.1, 0.5], 'end': [1.2, 2.9, 1.6], 'translation': [0.2, 0.0, 0.2], 'scale': [1, 1, 1], 'velocity': [0.0, -1.0, 0.0], 'density': 1000.0, 'color': [50, 100, 200]}]
这个其实就是读取的json文件。由于下面这个print所打印出来的。
接着output_xxx字样,显然是为了导出结果用的。从这里我们可以看出场景文件的用法。
所有json的键值对都被读入到config这个对象当中了。从这个对象可以获取任何参数。比如
substeps = config.get_cfg("numberOfStepsPerRenderUpdate")
这句话就是调用config对象的get_cfg方法,读取numberOfStepsPerRenderUpdate这个键,得到的值就是substeps。
接下来的这三行
是核心步骤,实际上就是实例化对象。
这个对象是ParticleSystem类的。
把config传给它,就是把场景参数传递给它。
然后builde_solver是构建流体解算器。然后初始化解算器。
让我们从ParticleSystem的 __init__开始
由于东西太多,我们大多数都略讲。
注意@ti.data_oriented是taichi的面向对象的用法。因此这是个太极的类。
从上到下依次步骤:
SPH_Taichi采用trimesh体素化采样粒子。每个体素中间放一个粒子
把这段代码随便拷到一个文件,运行一下(要记得更改模型文件路径哦)
import taichi as ti
import trimesh as tm # load the triangle mesh
import numpy as np
def main():
ti.init(arch=ti.cuda)
mesh = tm.load("E:/Dev/SPH_Taichi/data/models/Dragon_50k.obj")
voxelized_mesh = mesh.voxelized(pitch=0.02).fill()
voxelized_points_np = voxelized_mesh.points
num_particles_obj = voxelized_points_np.shape[0]
voxelized_points = ti.Vector.field(3, ti.f32, num_particles_obj)
voxelized_points.from_numpy(voxelized_points_np)
# np.savetxt("voxelized_points_np.csv",voxelized_points_np)
window = ti.ui.Window("Test voxelize", (768, 768))
canvas = window.get_canvas()
scene = ti.ui.Scene()
camera = ti.ui.make_camera()
camera.position(5, 2, 2)
while window.running:
camera.track_user_inputs(window, movement_speed=0.005, hold_key=ti.ui.LMB)
scene.set_camera(camera)
scene.ambient_light((1, 1, 1))
scene.point_light(pos=(0.5, 1.5, 1.5), color=(1, 1, 1))
scene.particles(voxelized_points, color = (0.68, 0.26, 0.19), radius = 0.01)
canvas.scene(scene)
window.show()
if __name__ == "__main__":
main()