域 (其实就是一个容器)

- ServletContext域:
一个WEB应用(项目)对应一个ServletContext,这个对象中保存的数据正在整个WEB项目中都有效;

  • 创建:服务器启动的时候;
  • 销毁:服务器关闭或项目移除后;

- HttpSession:
一次会话给客户端(浏览器)创建一个session。这个对象中保存的数据,一次会话(多次请求)内数据有效;

  • 创建:服务器第一次调用getSession()的时候;
  • 销毁:
    • 服务器非正常关闭(正常关闭:Session被序列化);
    • Session过期了:默认存活时间30分钟;
    • 手动调用session的invalidate()方法;

- HttpServletRequest:
一次请求创建一个request。这个对象中保存的数据,一次请求(请求链)内数据有效;

  • 创建:客户端向服务器发送一次请求;
  • 销毁:服务器为这次请求做出响应之后,销毁request;

【API操作】操作三个作用域对象的API

  • 存储数据:setAttribute(name,value);
  • 获得数据:getAttribute(name);
  • 删除数据:removeAttribute(name);
<think>我们正在使用YADE 2022.01a版本。要生成一个圆柱体容器并在其中填充颗粒,我们需要以下步骤: 1. 创建圆柱形容器(作为墙体)。 2. 在圆柱体内生成颗粒堆积。 注意:YADE中,圆柱形容器可以通过创建圆柱体侧壁和两个端盖(顶盖和底盖)来实现。通常,我们使用墙体(Wall)来定义容器边界。 步骤: 1. 导入必要的模块。 2. 定义圆柱体的几何参数(半径、高度)和位置。 3. 创建圆柱体的侧壁:实际上,在YADE中,我们可以使用多个墙体来近似圆柱形容器,但更简单的方式是使用圆柱体几何体(如Cylinder)并设置其为墙体。然而,YADE的墙体通常用无限平面(Wall)或由多个平面围成的区。对于圆柱形容器,我们可以使用圆柱形的墙体(Cylinder),但注意YADE中的Cylinder类可以表示一个圆柱体,并且可以设置为固定的墙体。 具体方法: - 使用`yade.wall.Cylinder`来创建圆柱体侧壁。注意,这个圆柱体是无限长的,所以我们需要两个平面(作为顶盖和底盖)来封闭它。 - 创建两个圆盘(作为顶盖和底盖),我们可以使用`yade.wall.Disk`或者用两个无限平面(Wall)来模拟。但是,由于圆柱体是轴对称的,通常我们使用两个与圆柱体轴线垂直的平面来作为顶和底。 另一种方法是使用三个墙体: a) 一个圆柱体侧壁(Cylinder),其轴线沿z轴,半径为R,位置在原点(或指定位置)。 b) 一个底盖(Wall),位于z=0处,法向量为(0,0,1) [注意法向量方向指向容器内部]。 c) 一个顶盖(Wall),位于z=height处,法向量为(0,0,-1)。 注意:墙体的法向量指向容器外部,这样颗粒就会在法向量指向的一侧被阻挡。但是,在YADE中,墙体默认是单向的,即法向量方向为墙体的正方向,颗粒从正方向穿过墙体会被阻挡,而从反方向则不会。因此,对于容器,我们通常将法向量指向容器内部,这样颗粒在容器内部碰撞到墙体时会被弹回。 然而,对于圆柱体侧壁(Cylinder),其法向量是径向向外的(即从轴线指向外),所以如果我们想要颗粒在圆柱体内部,那么圆柱体应该被设置为容器内壁,即我们需要将圆柱体的法向量方向反转(或者使用负半径)?实际上,YADE的Cylinder类可以通过设置`sense`参数来控制方向,但默认是外部(即内部是空的,外部是实体)。所以,如果我们想要一个圆柱形空腔,那么圆柱体墙体的法向量是向外的,颗粒在圆柱体外部会被阻挡,而在内部则不会。因此,我们需要将圆柱体墙体的方向反转,使得内部成为实体,外部为空?这不符合我们的需求。 实际上,我们想要的是颗粒在圆柱体内部,所以我们需要一个空腔。因此,我们应该使用一个圆柱体,其内部是空的,外部是实体,这样颗粒在圆柱体内部就不会受到墙体的阻挡(因为墙体的作用在外部)。这显然不对。 正确理解:在YADE中,圆柱体墙体(Cylinder)是一个无限长的圆柱面。它有两个面:内表面和外表面。默认情况下,圆柱体墙体的作用是在圆柱面的外部(即半径大于圆柱半径的区)是实体,而内部是空的。因此,如果我们想要一个圆柱形容器,我们需要将颗粒限制在圆柱体内部,那么我们应该将圆柱体墙体的作用设置为内部(即颗粒在圆柱体内部时不受此墙体影响,而一旦要穿出圆柱体则被阻挡)。但实际上,默认的圆柱体墙体是阻挡外部颗粒的,所以我们需要一个反向的圆柱体墙体。 解决方案:使用`Cylinder`类创建时,我们可以通过设置`sense`参数来控制作用方向。`sense`参数可以取0(双向),1(只阻挡从内到外,即法向量方向),-1(只阻挡从外到内)。但是,我们想要的是颗粒不能从内部穿出,所以我们应该设置`sense=1`(法向量方向为从轴线指向外,所以颗粒从内部(法向量反方向)穿到外部(法向量方向)时被阻挡)。但注意,默认的圆柱体墙体法向量是向外的,所以当颗粒从内向外运动(即从圆柱体内部穿过圆柱面到外部)时,会被墙体阻挡。这正是我们想要的。 因此,步骤为: 1. 创建圆柱体侧壁:`Cylinder(center=(0,0,h/2), axis=(0,0,1), radius=R, length=h, fixed=True, sense=1)` 注意:这里我们假设圆柱体轴线沿z轴,中心在(0,0,h/2),半径为R,高度为h。但是,实际上Cylinder类只表示一个圆柱面,没有高度限制(无限长),所以我们需要用两个端盖来限制高度。 2. 创建底盖:位于z=0,法向量为(0,0,1)(指向z轴正方向,即容器内部上方)。这样,当颗粒从z=0平面以下向上运动(即从容器内部向外部)时,会被底盖阻挡?实际上,我们想要颗粒在容器内部,所以底盖应该阻止颗粒向下运动(即z负方向)。因此,底盖的法向量应该指向容器内部(即向上),这样当颗粒从上方(容器内部)撞击底盖时,会被弹回。但是,墙体的作用是在法向量指向的一侧阻挡颗粒。因此,底盖应该这样设置:位置在(0,0,0),法向量(0,0,1)(向上),这样颗粒在底盖下方(z<0)时,如果向正方向(z正方向)运动,穿过墙体时不会被阻挡(因为墙体的阻挡是对于从法向量反方向穿过到正方向的情况)。这似乎不符合我们的需求。 实际上,在YADE中,墙体(Wall)的阻挡规则是:当颗粒从墙体的背面(法向量反方向一侧)穿过到正面(法向量方向一侧)时,会被阻挡。因此,对于底盖,我们想要阻挡颗粒掉到底面以下(即z<0),所以我们应该设置底盖的位置在z=0,法向量为(0,0,1)(指向z正方向)。这样,颗粒在z=0以下(背面)时,如果向z正方向运动(穿过墙体到正面),就会被阻挡。同时,颗粒在容器内部(z>0)时,向z负方向运动(穿过墙体到背面)则不会被阻挡(因为墙体是单向的,只阻挡从背面到正面的运动)。这显然不是我们想要的。 正确的做法是:我们想要颗粒在容器内部(0<z<h)中,所以底盖应该阻挡颗粒向下(z负方向)运动,即当颗粒到达z=0时,不能再向下。因此,底盖应该设置为:位置在z=0,法向量为(0,0,1)(向上),并且设置`sense=1`(默认),这样墙体只阻挡从背面(z<0)到正面(z>0)的运动,而不阻挡从正面到背面的运动。但这样设置,颗粒从容器内部(z>0)向下穿过底盖(到z<0)时不会被阻挡。所以我们需要一个反向的阻挡。 因此,我们需要将底盖的法向量设置为(0,0,-1)(向下),并且设置位置为(0,0,0)。这样,墙体背面是z>0(法向量反方向),正面是z<0。当颗粒从容器内部(z>0,背面)向下运动穿过墙体(到z<0,正面)时,就会被阻挡。同时,颗粒从外部(z<0)向上运动(穿过墙体到z>0)则不会被阻挡(因为我们只关心容器内部,外部颗粒可以忽略)。所以,底盖应该这样创建:`Wall(position=(0,0,0), axis=(0,0,-1), fixed=True)`。 同样,顶盖应该设置在z=h处,法向量为(0,0,1)(向下?不对,应该是向上?)。我们想要阻挡颗粒向上运动超过z=h,所以顶盖应该阻挡颗粒从z=h以下向上运动(超过z=h)。因此,顶盖的位置在(0,0,h),法向量为(0,0,1)(向上),这样当颗粒从容器内部(z<h,背面)向上运动穿过顶盖(到z>h,正面)时,会被阻挡。所以顶盖:`Wall(position=(0,0,h), axis=(0,0,1), fixed=True)`。 但是,这样设置顶盖的法向量向上,那么背面就是z<h,正面就是z>h。颗粒从背面(z<h)穿过到正面(z>h)时被阻挡,符合要求。 总结墙体: - 圆柱体侧壁:`Cylinder(center=(0,0,h/2), axis=(0,0,1), radius=R, length=h, fixed=True, sense=1)` 注意:Cylinder的创建参数中,center是中心坐标,axis是轴线方向向量,radius是半径,length在这里其实没有用(因为Cylinder是无限长的),所以我们只需要半径和轴线位置。实际上,Cylinder类只需要中心点、轴线方向和半径即可。高度由两个端盖控制。 - 底盖:`Wall(position=(0,0,0), normal=(0,0,-1))`,法向量向下,位置在(0,0,0) - 顶盖:`Wall(position=(0,0,h), normal=(0,0,1))`,法向量向上,位置在(0,0,h) 3. 生成颗粒:在圆柱体容器内生成颗粒堆积。我们可以使用YADE的填充函数,例如`yade.pack.randomPeriPack`或`yade.pack.SpherePack`来生成球体颗粒,然后将其添加到模拟中。 具体步骤: a) 创建一个`SpherePack`对象。 b) 在圆柱体区内生成球体。我们可以使用`SpherePack.makeCloud`方法,指定生成区为圆柱体(注意:圆柱体区可以用一个立方体区来近似,然后过滤掉圆柱体外的球体,但这样效率低)。或者,我们可以使用`makeCylinder`方法(注意:SpherePack类中并没有直接生成圆柱体内颗粒的方法,但我们可以用`makeCloud`并指定边界为圆柱体)。 我们可以这样定义圆柱体区:中心在(0,0,h/2),半径R,高度h。所以生成颗粒的范围:x和y在[-R,R]内,z在[0,h]内。但是,我们需要确保颗粒在圆柱体内部,所以我们可以先生成一个立方体区的颗粒,然后过滤掉圆柱体外的颗粒。 示例代码: ```python sp = SpherePack() # 生成一个立方体区内的颗粒,然后过滤 sp.makeCloud(minCorner=(-R, -R, 0), maxCorner=(R, R, h), rMean=rMean, rRelFuzz=rFuzz, num=numParticles, periodic=False) # 过滤:只保留在圆柱体内的颗粒(即颗粒中心到z轴的距离小于R,且z在[0,h]内) # 注意:我们生成时已经限制了z在[0,h],所以只需检查x和y sp = SpherePack([s for s in sp if math.sqrt(s[0]**2+s[1]**2) <= R]) # 注意:这样会重新生成一个SpherePack对象 ``` 但是,这样生成的颗粒可能仍然会有一部分在圆柱体外(因为颗粒有半径),所以我们应该考虑颗粒半径:颗粒中心到圆柱体轴线的距离加上颗粒半径不能超过圆柱体半径。同时,颗粒也不能与容器墙体重叠,但这在后续的模拟中会通过碰撞检测解决。在生成时,我们可以保守一点:颗粒中心到轴线的距离应小于等于R - s.radius(这样颗粒就不会超出圆柱体侧壁)。但是,这样生成可能会在边界处留下空隙。另一种方法是先不考虑边界,生成颗粒,然后在模拟过程中让颗粒沉降,并让墙体将颗粒推回容器内。 通常,我们先生成一个初始的颗粒云(可能有些颗粒在容器外),然后运行模拟,让颗粒在重力作用下沉降,并与墙体发生作用,最终稳定在容器内。 4. 将颗粒和墙体添加到模拟中。 5. 设置引擎(包括重力、碰撞检测、积分器等)。 因此,完整的代码框架如下: ```python from yade import pack, plot, qt import math # 参数 R = 0.5 # 圆柱体半径,单位米 h = 1.0 # 圆柱体高度,单位米 rMean = 0.05 # 颗粒平均半径 rFuzz = 0.2 # 半径随机变化范围(相对值) numParticles = 1000 # 颗粒数量(实际生成可能会少一些,因为过滤) # 创建墙体 # 1. 圆柱体侧壁 cylinder = yade.wall.Cylinder(center=(0,0,h/2), axis=(0,0,1), radius=R, fixed=True, sense=1) # sense=1表示只阻挡从内到外 cylinder.id = O.bodies.append(cylinder) # 2. 底盖 bottomWall = yade.wall.Wall(position=(0,0,0), normal=(0,0,-1), fixed=True) # 法向量向下,阻挡颗粒向下穿过z=0 bottomWall.id = O.bodies.append(bottomWall) # 3. 顶盖 topWall = yade.wall.Wall(position=(0,0,h), normal=(0,0,1), fixed=True) # 法向量向上,阻挡颗粒向上穿过z=h topWall.id = O.bodies.append(topWall) # 生成颗粒 sp = pack.SpherePack() sp.makeCloud(minCorner=(-R,-R,0), maxCorner=(R,R,h), rMean=rMean, rRelFuzz=rFuzz, num=numParticles, periodic=False) # 过滤:只保留颗粒中心在圆柱体内(且考虑颗粒半径,确保颗粒不会与侧壁重叠太多,但允许在后续模拟中调整) # 注意:这里我们只检查颗粒中心到轴线的距离小于(R-颗粒半径)的颗粒,这样颗粒就不会超出圆柱体。 sp = pack.SpherePack([s for s in sp if math.sqrt(s[0]**2+s[1]**2) <= R - s[2]]) # s[2]是半径 # 将颗粒添加到模拟中 sp.toSimulation() # 默认材质0 # 设置引擎 O.engines = [ ForceResetter(), InsertionSortCollider([Bo1_Sphere_Aabb(), Bo1_Wall_Aabb()]), InteractionLoop( [Ig2_Sphere_Sphere_ScGeom(), Ig2_Wall_Sphere_ScGeom()], [Ip2_FrictMat_FrictMat_FrictPhys()], [Law2_ScGeom_FrictPhys_CundallStrack()] ), NewtonIntegrator(gravity=(0,0,-9.81), damping=0.4), # 可以添加PyRunner用于检查平衡状态 ] # 设置时间步 O.dt = 0.01 * PWaveTimeStep() # 保存状态以便后续查看 O.saveTmp() # 运行模拟(可以运行一段时间直到颗粒稳定) #O.run(10000, True) # 如果想实时查看,可以打开QT界面 qt.View() ``` 注意:上述代码中,过滤颗粒的条件是`math.sqrt(s[0]**2+s[1]**2) <= R - s[2]`,这确保了颗粒中心到轴线的距离加上颗粒半径不会超过圆柱体半径(即颗粒不会超出圆柱体侧壁)。但是,这样过滤可能会使得靠近圆柱体侧壁的颗粒被过滤掉,导致靠近边界处颗粒较少。另一种方法是不过滤,让颗粒在模拟中与墙体发生碰撞自然调整位置。我们可以尝试不过滤,然后运行模拟,让颗粒在重力作用下沉降。 因此,我们可以先不进行过滤,而是生成一个立方体区内的颗粒,然后运行模拟,让颗粒在重力作用下沉降,同时与墙体碰撞,最终稳定在容器内。 修改生成颗粒部分: ```python sp.makeCloud(minCorner=(-R,-R,0), maxCorner=(R,R,h), rMean=rMean, rRelFuzz=rFuzz, num=numParticles, periodic=False) sp.toSimulation() ``` 这样生成的颗粒可能有一部分在圆柱体外,但后续模拟中墙体会将它们推回。 另外,注意我们使用的是`yade.wall.Cylinder`和`yade.wall.Wall`,它们都需要相应的碰撞几何体和相互作用。在引擎中,我们已经为球体和墙体添加了碰撞检测(Bo1_Sphere_Aabb和Bo1_Wall_Aabb)以及相互作用(Ig2_Wall_Sphere_ScGeom和Law2_ScGeom_FrictPhys_CundallStrack)。 但是,注意我们创建的圆柱体墙体(Cylinder)是一种特殊的墙体,在碰撞检测中需要使用`Bo1_Cylinder_Aabb`(如果存在的话)?实际上,在YADE中,Cylinder墙体也是由Wall类派生的,所以我们可以使用`Bo1_Wall_Aabb`来创建它的几何体。但是,为了确保正确,我们可以查看YADE文档。在YADE中,圆柱体墙体的碰撞检测已经内置,我们使用`Ig2_Cylinder_Sphere_ScGeom`来处理圆柱体和球体的碰撞。因此,我们需要修改相互作用几何体创建部分: 将`Ig2_Wall_Sphere_ScGeom()`替换为`Ig2_Cylinder_Sphere_ScGeom()`和`Ig2_Wall_Sphere_ScGeom()`,因为有两种墙体(圆柱体和平面墙)。我们可以这样写: ```python InteractionLoop( [Ig2_Sphere_Sphere_ScGeom(), Ig2_Wall_Sphere_ScGeom(), Ig2_Cylinder_Sphere_ScGeom()], [Ip2_FrictMat_FrictMat_FrictPhys()], [Law2_ScGeom_FrictPhys_CundallStrack()] ) ``` 但是,注意:顶盖和底盖是`Wall`类型,而圆柱体是`Cylinder`类型,所以我们需要同时添加这两种几何交互。 另外,在碰撞检测中,我们需要为圆柱体添加边界体(bounding volumes)。由于圆柱体是无限长的,我们可能需要使用`Bo1_Cylinder_Aabb`来创建它的Aabb?实际上,在YADE中,圆柱体墙体的Aabb是自动创建的,并且覆盖整个空间?这显然效率低下。因此,我们可以手动设置圆柱体的Aabb范围,或者使用其他方法来优化。 但是,为了简单起见,我们可以先这样处理,如果颗粒数量不多,可以运行。 另外,我们也可以使用`yade.utils.crossSectionModule`中的`gtsSurface2Facets`来创建一个圆柱体的三角网格表面,然后作为普通几何体(Facet)加入,但这样计算量较大。因此,我们还是使用墙体。 综上,我们调整后的代码为: ```python from yade import pack, plot, qt import math # 参数 R = 0.5 # 圆柱体半径,单位米 h = 1.0 # 圆柱体高度,单位米 rMean = 0.05 # 颗粒平均半径 rFuzz = 0.2 # 半径随机变化范围(相对值) numParticles = 1000 # 颗粒数量 # 创建墙体 # 1. 圆柱体侧壁 cylinder = yade.wall.Cylinder(center=(0,0,h/2), axis=(0,0,1), radius=R, fixed=True, sense=1) # sense=1表示只阻挡从内到外 cylinder.id = O.bodies.append(cylinder) # 2. 底盖 bottomWall = yade.wall.Wall(position=(0,0,0), normal=(0,0,-1), fixed=True) # 法向量向下,阻挡颗粒向下穿过z=0 bottomWall.id = O.bodies.append(bottomWall) # 3. 顶盖 topWall = yade.wall.Wall(position=(0,0,h), normal=(0,0,1), fixed=True) # 法向量向上,阻挡颗粒向上穿过z=h topWall.id = O.bodies.append(topWall) # 生成颗粒 sp = pack.SpherePack() sp.makeCloud(minCorner=(-R,-R,0), maxCorner=(R,R,h), rMean=rMean, rRelFuzz=rFuzz, num=numParticles, periodic=False) sp.toSimulation() # 设置引擎 O.engines = [ ForceResetter(), InsertionSortCollider([Bo1_Sphere_Aabb(), Bo1_Wall_Aabb(), Bo1_Cylinder_Aabb()]), # 注意添加了Bo1_Cylinder_Aabb InteractionLoop( [Ig2_Sphere_Sphere_ScGeom(), Ig2_Wall_Sphere_ScGeom(), Ig2_Cylinder_Sphere_ScGeom()], # 注意添加了圆柱体与球体的相互作用 [Ip2_FrictMat_FrictMat_FrictPhys()], [Law2_ScGeom_FrictPhys_CundallStrack()] ), NewtonIntegrator(gravity=(0,0,-9.81), damping=0.4), ] # 设置时间步 O.dt = 0.01 * PWaveTimeStep() # 保存状态 O.saveTmp() # 运行模拟(先运行一段时间,比如10000步,或者直到颗粒稳定) # 可以添加PyRunner来检查动能,以判断是否稳定 def checkUnbalanced(): if O.iter > 1000 and unbalancedForce() < 0.05: O.pause() print("平衡状态达到") # 否则继续运行 # 将PyRunner加入引擎 O.engines = O.engines + [PyRunner(command='checkUnbalanced()', iterPeriod=100)] # 运行 O.run(10000, True) # 打开QT界面 qt.View() ``` 注意:上述代码中,我们添加了`Bo1_Cylinder_Aabb`来处理圆柱体的Aabb,以及`Ig2_Cylinder_Sphere_ScGeom`来处理圆柱体与球体的碰撞几何。 另外,我们添加了一个`PyRunner`来检查系统是否达到平衡(通过`unbalancedForce`函数)。`unbalancedForce`是YADE中用于计算系统不平衡力的函数,当值小于0.05时认为系统达到平衡。 以上就是在YADE中创建圆柱形容器并生成颗粒堆积的基本步骤。用户可以根据实际需求调整参数。 注意:如果颗粒数量较多,可能需要较长的计算时间。另外,初始生成的颗粒可能会在圆柱体外,但随着时间的推移,颗粒会沉降到容器内并达到稳定。 最后,如果用户需要保存颗粒堆积状态,可以使用`yade.utils.save`函数。 相关问题: 1. 如何调整颗粒的物理属性(如摩擦系数、弹性模量)? 2. 如何提高颗粒生成效率(避免过多的颗粒生成在容器外)? 3. 如何在圆柱体容器中实现周期性加载(如施加压力)?</think>在YADE 2022.01a中创建圆柱形容器并生成颗粒堆积的步骤如下: ### 1. 导入必要模块 ```python from yade import utils, pack, plot, qt import math ``` ### 2. 定义容器参数 ```python radius = 0.5 # 圆柱体半径(m) height = 1.0 # 圆柱体高度(m) thickness = 0.02 # 容器壁厚(m) ``` ### 3. 创建圆柱形容器 使用三个墙体组件构建封闭容器: ```python # 圆柱侧壁(无限长圆柱面) cylinder = utils.wallCylinder(axis=(0,0,1), radius=radius, center=(0,0,height/2), sense=1) # 底部盖子 bottom_wall = utils.wall(position=(0,0,0), normal=(0,0,1)) # 顶部盖子 top_wall = utils.wall(position=(0,0,height), normal=(0,0,-1)) # 添加到模拟 container_ids = [ O.bodies.append(cylinder), O.bodies.append(bottom_wall), O.bodies.append(top_wall) ] ``` ### 4. 生成颗粒堆积 ```python # 颗粒参数 mean_radius = 0.05 # 平均半径(m) radius_dev = 0.2 # 半径浮动范围(0.2=±20%) # 在圆柱体内生成颗粒 particle_pack = pack.SpherePack() particle_pack.makeCloud( minCorner=(-radius, -radius, 0), maxCorner=(radius, radius, height), rMean=mean_radius, rRelFuzz=radius_dev, num=500, # 颗粒数量 seed=1 # 随机种子 ) # 过滤圆柱体外颗粒 filtered_particles = [] for sphere in particle_pack: x, y, z, r = sphere if math.sqrt(x**2 + y**2) <= radius - r: # 确保颗粒在容器内 filtered_particles.append((x, y, z, r)) # 添加颗粒到模拟 particle_ids = O.bodies.append([sphere(s[0:3], s[3]) for s in filtered_particles]) ``` ### 5. 设置物理引擎 ```python O.engines = [ ForceResetter(), InsertionSortCollider([Bo1_Sphere_Aabb(), Bo1_Wall_Aabb()]), InteractionLoop( [Ig2_Sphere_Sphere_ScGeom(), Ig2_Wall_Sphere_ScGeom()], [Ip2_FrictMat_FrictMat_FrictPhys()], [Law2_ScGeom_FrictPhys_CundallStrack()] ), NewtonIntegrator(gravity=(0,0,-9.81), damping=0.4) ] # 设置材料属性 mat = FrictMat(young=1e8, poisson=0.3, frictionAngle=0.5) O.materials.append(mat) ``` ### 6. 运行模拟 ```python # 设置时间步 O.dt = 0.01 * PWaveTimeStep() # 运行5000步使颗粒沉降 O.run(5000, True) # 可视化 qt.View() ``` ### 关键说明: 1. **容器构建**: - `wallCylinder`创建无限长圆柱面,`sense=1`表示法向向外 - 两个`wall`对象创建顶/底盖 - 法向量方向决定哪侧为实体(颗粒碰撞面) 2. **颗粒生成**: - `makeCloud`在包围盒内生成颗粒 - 数学过滤确保颗粒在圆柱内:$ \sqrt{x^2 + y^2} \leq R - r $ - 考虑颗粒半径避免初始穿透 3. **物理参数**: - `young`:杨氏模量 (Pa) - `frictionAngle`:摩擦角 (弧度) - `damping`:数值阻尼系数 [^1] ### 可视化效果 运行后可通过QT查看: - 红色:容器墙体 - 彩色球体:颗粒 - 按`ESC`退出实时视图
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NoBugsBoy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值