ANSYS耦合终极解决方案

这两天很忙,源于自己对论文中可能出现的问题估计不足,不过话说回来,很多问题着实也是在实践过程中才发现其中奥秘。不过这段时间效率低下是一定的了,想必和网上多了有很大关系。看来是我真正下决心息网的时候到了,成功的前提是有选择性地放弃,看来这句话是对我说的。而且,看着即将完成的一篇论文,怎么看怎么像是我写博客的风格,囧。博客对生活影响真大啊!

好了,言归正传,刚才在仿真论坛发现了一篇好贴《高效耦合小程序》,si13俨然是个天才,程序写得太牛了,我读了三遍才理解其中奥秘,不禁啧啧称奇。对其作品更是五体投地,相当佩服。首先来围观下面si13编写的APDL代码:

说明:其中加粗的部分需要根据不同的分析自行修改。

!**************************************
allsel                                         !最好保留这句命令
!*******将从属节点编号依次存入数组****************
cmsel,s,slavenode
*get,count1_node,node,0,count
*del,slave_node
*dim,slave_node,array,count1_node
*get,slave_node(1),node,0,num,min
*do,i,2,count1_node
  slave_node(i)=ndnext(slave_node(i-1))
*enddo 
!*******将主节点编号依次存入数组****************
allsel
cmsel,s,masternode
*get,count2_node,node,0,count
*del,master_node
*dim,master_node,array,count2_node
*get,master_node(1),node,0,num,min
*do,i,2,count2_node
  master_node(i)=ndnext(master_node(i-1))
*enddo
!********将与从属节点耦合的节点数组初始化****************
*del,cp_node
*dim,cp_node,array,count1_node
*do,i,1,count1_node
    cp_node(i)=0
*enddo
!*********开始选择程序****************
allsel
cmsel,s,masternode
*do,i,1,count1_node      
    kk=1   
    k=1  
   
     *dowhile,kk    
      k=nnear(slave_node(i))
    nsel,s,cp,,all
    kk=nsel(k)+0.001   
    allsel
       cmsel,s,masternode
        nsel,u,node,,k
        cm,masternode,node       
        *enddo   
           
    cp_node(i)=k   
      
*enddo
!*******选择完毕****************
!*******开始耦合****************
allsel,all
/prep7
*do,i,1,count1_node
    cp,next,UX,slave_node(i),cp_node(i)
    cp,next,UY,slave_node(i),cp_node(i)
    cp,next,UZ,slave_node(i),cp_node(i)
*enddo
!*******耦合完毕****************

过去常见的耦合命令,主要分三步(以钢筋与混凝土耦合为例):

  1. 选择钢筋线上的节点;
  2. 通过新定义的数组,对这些节点进行排序;
  3. 用一个循环,是这些钢筋上的节点与其周围最近的节点进行耦合。

最常见的耦合命令流如下(这是我两年前做另一个课题的时候用的):
cmsel,s,ouhe

*get,max1,node,0,count  !取得节点数目
*dim,steel,,max1 !定义“节点数”长度的数组
*get,nod1,node,0,num,min !最小节点编号定义给nod1
steel(1)=nod1 !数组第一个位置是最小节点的编号
*do,i,2,max1 !对数组进行排序
steel(i)=ndnext(steel(i-1))
*enddo
allsel
nsel,all !选择全部节点

jj=1
*do,i,1,max1 !对数组中的节点,一一与周围和它最近的节点进行耦合
cp,jj,ux,steel(i),nnear(steel(i))
cp,jj+1,uy,steel(i),nnear(steel(i))
cp,jj+2,uz,steel(i),nnear(steel(i))
jj=jj+3
*enddo

这样做其实是很大弊端的,还是拿钢筋混凝土举例:用上面的代码,容易使得钢筋上的节点与钢筋上另外的节点、或者与混凝土中两个节点进行耦合——也就是说,会出现一对多的情况,而这在耦合中是不允许的。

在我两年前的那次分析,做的是一个组合结构,不是钢筋混凝土,而且我在网格划分的时候,特别注意了让参与耦合的两对节点举例比其他节点更接近。这样就使得用上面的命令实现完美一对一耦合。但在网格不好控制的时候,麻烦可就大了。

所以后来见过一种改进的方法,将混凝土中的节点也进行排号,然后进行与钢筋节点进行耦合。这样成功地避免了自己耦合自己的情况,但已经耦合过的节点二次被耦合,则依然容易出现。

si13的这套命令流,应该是把所有问题都解决了,perfect! 下面对他的程序详细地研究研究,学习一下他的编程思想,所以有必要把他的程序再写一遍~

为了便于理解,下面仍以钢筋与混凝土耦合为例,不再区分主节点与附节点。

allsel          !全部选择
!将钢筋中节点存入数组
cmsel,s,slavenode !选择钢筋节点
*get,count1_node,node,0,count !得到钢筋节点的总数
*del,slave_node !清空数组变量,相当于slave_node=
*dim,slave_node,array,count1_node !定义用来“盛装”钢筋节点的数组
*get,slave_node(1),node,0,num,min !开始对钢筋节点进行排序,并存入数组
*do,i,2,count1_node
  slave_node(i)=ndnext(slave_node(i-1))
*enddo 
!**下面是将混凝土中节点存入数组,方法同上,于是就不解释了
allsel
cmsel,s,masternode
*get,count2_node,node,0,count
*del,master_node
*dim,master_node,array,count2_node
*get,master_node(1),node,0,num,min
*do,i,2,count2_node
  master_node(i)=ndnext(master_node(i-1))
*enddo
!*新定义一个数组,专门用来存放混凝土中参与耦合的节点编号
*del,cp_node
*dim,cp_node,array,count1_node
*do,i,1,count1_node
    cp_node(i)=0
*enddo
!*最精妙的核心代码来啦
allsel
cmsel,s,masternode   !选择混凝土中的节点
!外层循环是为了给cp_node数组赋值,所以数组中元素个数为钢筋节点数
*do,i,1,count1_node      
    kk=1   
    k=1   
!内层循环是为了判断钢筋最近的节点是否已经参与过耦合
     *dowhile,kk    !循环条件,若kk>0则循环继续,若kk<=0则循环终止
      k=nnear(slave_node(i))  !将距钢筋中第i个节点最近的节点编号赋给k
    nsel,s,cp,,all  !选择所有已经耦合的节点,这种用法我是第一次看到
    kk=nsel(k)+0.001    !若上面的节点k不曾参与过耦合,则nsel命令不能将其选中,此处nsel(k)=-1,kk=-0.999<0,此部分循环终止;若上面的节点k已经参与过耦合,则nsel命令可以将其选中,此处nsel(k)=1,kk=1.001>0,循环继续,查找其他与第i个钢筋节点最近的混凝土节点的情况。
    allsel
       cmsel,s,masternode  !选择混凝土节点
        nsel,u,node,,k    !排除出刚才确定的准备参加耦合的混凝土节点
        cm,masternode,node        !重新定义混凝土节点选择集,这是为了下次选择节点的时候,不将已经判读过的节点放在考虑之列
        *enddo   
           
    cp_node(i)=k    !将经过判断的k点编号赋予给混凝土参与耦合数组
      
*enddo
!开始耦合,耦合对象为钢筋中全部节点,以及混凝土中一部分专门用来耦合的节点,二者一一对应,而且还位置确定。
allsel,all
/prep7
*do,i,1,count1_node
    cp,next,UX,slave_node(i),cp_node(i)
    cp,next,UY,slave_node(i),cp_node(i)
    cp,next,UZ,slave_node(i),cp_node(i)
*enddo

完毕,这个程序越看越喜欢~留在这里,当个记录,用的时候过来拿,哈哈。

长河

在曾经的博客时代,是“首个桥隧工程领域独立博主”,目前是一名默默耕耘的普通高校教师。一家之言,仅供参考,未必成熟、绝不权威。

相关推荐

17 条评论

  1. 怎么这段运行了很久 :cry:

    • @凯 这段我多次用过,代码本身没问题,而且运行时间的确很长,建议观察CMD窗口,是建立数组更慢还是建立耦合的过程更慢,也有可能是模型过于复杂,需要耦合的节点过多,超过计算机内存资源,调用虚拟内存导致的速度慢

  2. 明月

    请问在定义钢筋和混凝土节点单元组之前 如何选择钢筋和混凝土的节点, 钢筋是按钢筋线上的点来选吗?那混凝土是怎么选?是选排除钢筋线之后的点吗?

    • @明月 在建立模型的初期,就需要考虑后面选择的问题,及时地用cm命令,创建集合是正道

  3. […] 3.三维-三维单元耦,选取哪个点进行耦合?应对稍稍复杂的模型,这个耦合的程序应该如何修改?(参考这个耦合终极解决方案) […]

  4. 於进

    咨询一个问题,现在想提取耦合节点处的支反力!怎样提取呢?

  5. @feson 这是在一个内部循环做的,实际上已经通过外层循环进行过耦合,然后再通过这个来判断是否已经耦合过,避免重复耦合

  6. 疑问
    nsel,s,cp,,all !选择所有已经耦合的节点,这种用法我是第一次看到
    这个选择是在耦合之前做的吧,怎么知道哪些是已经耦合过的,按我的理解是选择在masternode里的节点
    不能理解啊

  7. Hello! This is my first visit to your blog! We are a team of volunteers and starting a new project in a community in the same niche. Your blog provided us valuable information to work on. You have done a marvellous job!

  8. huang840828

    楼上也姓黄啊,呵呵。
    答案是,是的,呵呵

  9. 你好,请问cmsel,s,slavenode里面的slavenode是不是以前已经定义过的名词?

  10. @李丹 耦合之后不进行合并;只耦合一个方向的情况,在循环里不设置其他方向即可了

  11. 李丹

    那耦合之后,还需要合并节点嘛,如果节点合并了耦合还有意义嘛?如果是无粘结的预应力,预应力钢筋只要耦合y方向,其他钢筋要耦合所以自由度,又怎么解决呢?

  12. @尹俊禄 静力问题,又不涉及到非线性方程求解,为啥还能不收敛的?再有,泊松比要按照材料的实际情况添加,不能自己定义的

  13. 尹俊禄

    老兄你好,我是一位初学ansys者,在进行结构静应力分析中,当选取的泊松比较大时,同一个模型却不再收敛,网格进行细分后,仍不能解决此问题。所以想请教下您,如何解决此问题。急用,望您能给予帮助!不胜感激!

  14. 尹俊禄

    老兄你好,我是一位初学ansys者,在进行静应力结构分析中,当选取的泊松比较大时,同一个模型却不再收敛,网格进行细分后,仍不能解决此问题。所以想请教下您,急用,网您能给予帮助!不胜感激

发表评论

您的电子邮件地址不会被公开,必填项已用*标注。