hello,大家好呀。今天是2020-12-09。又到了今天的脚本时间,昨天因为我忙着别的事了,所以托更了一天了,抱歉抱歉。今天给大家带点硬核的东西,三维多晶体Voronoi多边形建模。
如果有做晶体塑性力学的小伙伴应该懂,其实做这个是不大容易的,关是建模就已经是拦路虎了。上次出了一期关于2D多晶粒建模的脚本,得到许多粉丝的赞,谢谢大家的认可。也有粉丝留言说想要3D的建模脚本,当然,我既然写了二维的,肯定会有三维的。今天我就给大家隆重介绍一下我们新的脚本,三维多晶体建模。(没看过二维的小伙伴先看二维的)
还记得,当年我自己在做这个三维多晶建模时,其实我自己也做二次开发不久,处于什么都懵懂的状态。网上基本上是没有这类的免费资源。当时我年少不服气,就是不想买(其实买了,别人也不会把源脚本卖给你的,只是给你一个插件)。于是我在家闭关,苦思冥想,皇天不负有心人,终于有一天,我算是小彻小悟了。虽然这个过程比较艰辛,但是我也从中收益匪浅,我写脚本的能力,也是在这个建模过程中得到了很大的锻炼。未来的你终是会感谢现在正在奋斗的你。
大家也一样,喜欢一个事,要坚持下去,别人能做的,为什么我们不能做呢,别人会写的,为什么我们不能写呢。坚持下去,你们就是最强的。👍👍
收敛一下,不喂鸡汤了,接下来,就开始我们今天的教学吧。
其实三维与二维的建模思路是一致的,但是难度上是天差地元的,二维的着实简单。三维的建模还是有点难。那么今天,我就要把这个说起来难的,给大家解释清楚了,让你们每个人都会写。首先上一张最终的结果图:
下面我们就来说,怎么做。
1 Voronoi类对象的数据生成
这一步特别重要,在abaqus里写脚本要有两个步骤,一个是数据处理,第二个就是在abaqus里实现。这一步,就是最重要的数据处理一步。大家想,你想做三维的多晶体模型,是不是需要这些多面体的信息才能在abaqus里画出来?首先你得有这些信息,你才能在abaqus里画出来,对不对,所幸的是,生成这个三维多面体的数据信息非常的简单,因为已经有大佬帮我们做好了,这个东西就是scipy,scipy是我个人最推崇的数据分析四大必备神包之一,另外三大将分别是numpy、sympy和matplotlib。做过python数据分析的人应该知道,这些包。这几个包加起来,够你分析任何数据了。
今天我们用到的包,就是Voronoi类,其实我在二维建模里已经讲过了,这里再讲一遍,足以看得出这个东西的重要性。我们只需要简简单单的把随机种子的给它,它就能返回给我们一个voronoi对象,就是我们需要的三维多面体数据。代码怎么写呢:
上面的是导入包,下面的是取这个多边形对象的两个非常重要的属性。真正生成的,就两句话,一句是生成随机种子点,一句是调用Voronoi类,生成vor对象。到此位置,我们的vor三维多面体数据就已经生成了,但是,数据处理,还并未结束。因为,它给你的,并不总是你想要的,你还需要把你不想要的东西给除去。这就是咱们做数据处理的目的。
大家从上面的代码可以看到,我把对象的两个属性分别给了两个变量,一个是vertices,一个是edges。这两个属性是什么,如果又不知道的,请看我前两个关于二维建模的例子。vertices指的是多面体的点坐标,edges指的某个平面上,所有边的连接点。举个实际的例子看,vertices是点坐标很好理解,这个edges是平面上有哪些点,它的数据,就是vertices的编号。-1表示无限远处,没有vertices与之对应:
之前我做了两个版本的二维建模,其实有个原因就是,无限远的点到底算不算。再二维中有两个选择,三维里,我推荐是别算了无限远的点位置了,把种子点的范围弄大一点,包裹住你想要的基体,然后在生成的多晶粒里直接切割处理就行。我这么说大家可能有点懵,等会看例子就明白了。
那么数据处理好了之后,有了多面体的空间信息,就要在abaqus里重构了,重构怎么做,咱们继续说:
2 Abaqus重构Voronoi
在abaqus里重构说起来挺简单,其实做起来,本质也不难。难就难在,你可能都不知道怎么在cae里做,大家如果不信的画,自己在abaqus里画个正四面体处理试试看,挑战成功的,留言告诉我,给你点个大大的赞,我就不剧透了,我只说脚本怎么做了。
我这里是把线和面一块儿生成了。什么意思呢,首先edges是一个列表,里面的每一个元素都是一个面上的信息,对edges做循环,然后把一个面上的线生成完之后,直接生成面。继续下一个循环。
画线的函数WirePolyLine,需要的参数是一个面上的点坐标。所以啊,由于对象里没有直接的面上点坐标类,就需要对它进行数据处理了,把edges里的点编号变成实际的坐标。
实现的脚本是,这里还要提一点,程序做了一个判断,31行,如果edge里有含有-1,说明这个面里有无限远的点,没有直接的点坐标与之对应,意味这,这个面就构成不了。就放弃生成这个面了。这里要注意下。
然后我还做了一个处理,当然这个处理可有可无,只是我个人的原因。就是下面这段
到此为止,我们还差最后两句话,所有的重构脚本就已经写的差不多了。这两句话就是把面弄成体,很简单,两句话。
如果现在运行是可以出结果的。比如,我们测试一下两种情况,加不加上述的代码,生成的多面体,有什么区别。(其实到这一步之前,我是经过大量测试才确保脚本正确的,没有人写脚本是一遍过的,都是不停的尝试,犯错。大家在写的时候也一样,经常去运行测试。软件这东西,随便运行,又不会犯什么大错,最多就是重启电脑,最差就是重装系统,还怕个什么,都是做二次开发的人,装个系统应该不是难事吧,有不会装系统的的跟我说,我单独指点一下。) 好,测试一下。下面这个图,是没经过算法处理的,生成出的模型有点像机动战士的,可以看出,它有些点离模型很远。
那么加上这段代码,处理后的效果,如下图。大家现在应该知道那段代码是干什么了吧。
改下种子点的数量,然后生成一个晶粒稍微细一点的:
大家看上面那两个图是不是挺别扭的,毛毛刺刺的,看起来很是不舒服。因为想做成四四方方的还差最后一步,切割。
3 切割
其实说实话,在abaqus里做切割我是真没相出什么好办法来,我唯一想到的就是在assembly里做布尔运算。然后abaqus的布尔运算还没有交集,所以,只能做一个带空腔的体,然后用布尔运算的cut了。如果大家有什么好的切割想法,欢迎留言告诉我。跟我说一下你的想法即可,脚本我来写。
下面说一下我的想法,首先建立一个空腔的体。空腔也是用布尔运算做出来的。然后再利用这个空腔去切割。
其实这段切割,着实花费了我不少时间。主要的思想就是通过布尔运算切割出来。这段算法,我目前还没想到更好的切割办法,用布尔运算凑合着,大家如果有想法,欢迎跟我讨论。
与二维的一样,其实今天写的也是用扩张的办法,但是这个办法,弊端就是耗时比较久,最好的是还是要把无限边画出来。
这段解释起来极度的痛苦,大家可以下载一下我写的,然后自己研究研究,如果有问题,随时可以联系我,我每天都会看私信,b站和公众号都会看。
到此为止,我们的整个程序就写完了,运行测试一下:还是没问题的,如果你想画比较细的晶粒的话,需要布置较多的种子点,运行的有点慢。如果想要运行的快的话,只有用第二种办法了,后期有机会我会跟大家讲,version2.0版本的三维建模。
改一下种子的数目,晶粒就会变得细小了,但是会伴随着比较场的运行时间。这个是我的问题,这种方法的弊端,后面我会写个更好的。
最终的源代码我就不放截图了,比较长。我放在评论区的置顶,大家可以自己下载。
好啦,今天的内容,确实有点多,对于刚学脚本没多久的你们的确是个挑战,大家不妨课后看一下,每一步是怎么做的,拆分着去运行,去学习一下思路。
我们下期再见啦。88