你好,我把简化后的代码写在下面了
import taichi as ti
ti.init(arch=ti.cuda,device_memory_fraction=0.5)
dt=1e-3
step=1600
v_number=36
v_res=v_number-1
cloth_length=4.0
vec=lambda : ti.Vector.field(3,dtype=ti.f32)
scale=lambda: ti.field(dtype=ti.f32)
pos=vec()
force=vec()
vel=vec()
stiffness=scale()
drag_damping=scale()
loss_n=scale()
ti.root.dense(ti.ijk,(step,v_number,v_number)).place(pos,force,vel)
ti.root.place(loss_n,stiffness,drag_damping)
ti.root.lazy_grad()
spring_date=ti.Vector.field(3,dtype=ti.f32,shape=(v_number,v_number,4))
traj=ti.Vector.field(3,dtype=ti.f32,shape=(2,step))
@ti.kernel
def cloth_init():
stiffness[None]=1000.0
drag_damping[None]=1.0
for t,i,j in pos:
pos[t,i,j]=ti.Vector([1.0+i*(cloth_length/v_res),1.0,1.0+j*(cloth_length/v_res)])
vel[t,i,j]=ti.Vector([0.0,0.0,0.0])
force[t,i,j]=ti.Vector([0.0,-9.8,0.0]) * 1.0
spring_init()
@ti.func
def get_x(n:ti.i32) ->ti.i32:
ax=0
if (n==0):
ax=1
elif (n==2):
ax=-1
else:
ax=0
return ax
@ti.func
def get_y(n:ti.i32)->ti.i32:
ax=0
if (n==1) :
ax=-1
elif (n==3):
ax= 1
else:
ax = 0
return ax
@ti.func
def spring_init():
for i,j,k in spring_date:
spring_coord = ti.Vector([get_x(k),get_y(k)])
coord_neigh = spring_coord + ti.Vector([i,j])
if (coord_neigh.x>=0) and (coord_neigh.x<=v_res) and (coord_neigh.y>=0) and (coord_neigh.y<=v_res):
spring_date[i,j,k]=ti.Vector([cloth_length/v_res,coord_neigh.x,coord_neigh.y])
else:
spring_date[i,j,k]=ti.Vector([0.0,0.0,0.0])
@ti.func
def spring_force(t:ti.i32,i:ti.i32,j:ti.i32):
p1=pos[t-1,i,j]
######################################
force[t,i,j] += - vel[t-1,i,j] * 0.0
######################################
for n in range(spring_date.shape[2]):
spring_length=spring_date[i,j,n][0]
if spring_length != 0.0 :
x=int(spring_date[i,j,n][1])
y=int(spring_date[i,j,n][2])
p2=pos[t-1,x,y]
dp=p1-p2
force[t,i,j] += -stiffness[None]*(dp.norm()/spring_length -1)*dp.normalized()
@ti.kernel
def simulation(t:ti.i32):
for i,j in ti.ndrange(v_number,v_number):
spring_force(t,i,j)
if ((i == 0 and j == 0 ) or (i == v_res and j == 0 )):
pass
else:
vel[t,i,j]=(vel[t-1,i,j]+(force[t,i,j]/1.0)*dt)*ti.exp(-dt * drag_damping[None])
pos[t,i,j]=pos[t-1,i,j]+vel[t,i,j]*dt
@ti.kernel
def compute_loss(t:ti.i32):
loss_n[None]=(pos[t,int(v_res/2),0]-pos[t,int(v_res/2),v_res]).norm()
cloth_init()
with ti.ad.Tape(loss=loss_n,clear_gradients=True):
for j in range(1,step):
simulation(j)
compute_loss(step-1)
print("loss=",loss_n[None])
print("vel",vel.grad[1595,int(v_res/2),3])
print("force",force.grad[1595,int(v_res/2),3])
print("pos",pos.grad[1595,int(v_res/2),3])
print("stiffness",stiffness.grad[None])
print("drag_damping",drag_damping.grad[None])