marc焊接仿真二次开发-以几何位置激活生死单元的方法? 50

浏览:991

二次开发指南上和网上关于生死单元的二次开发uactive()大多都是用单元号作的。这样在遍历单元格时很容易判断所遍历的单元生死状态,但对模型分网的网格单元号是有要求的。二次开发指南上网格单元号沿焊接路径方向有规律增加。可是对于不在marc上建模分网的焊接模型,网格号很难满足上述要求。

此时想用遍历单元与移动的热源中心相对位置来决定是否激活单元。我们看到二次开发指南中将生死单元状态另写入以文件中,仿照此方法,在初始化网格生死状态后,将所有会出现生死状态变化的单元的单元号和生死状态写入一.txt文件。进入焊接工况下,为判断遍历单元生死状态以决定生死操作,先将.txt文件读入二维向量,进行生死操作后删除原.txt文件,再将更新后的二维数组数据重新写入.txt文件。

这种方法效率极低,运行极慢。各位仿真大佬有没有效率更高的方法,十分感谢。另附现有代码。

另外,marc程序中是否有与fluent相似的数据结构,即用单元的结构体链表存储各个单元的各向参数。我看到elevar()函数可以调出的项里没有单元的生死状态。

还有,弱弱问一句,死单元里有温度和热流等参数吗?

代码如下:

subroutine uactive(m,n,mode,irststr,irststn,inc,time,timinc) 

   include 'D:\MSC.Software\Marc\2016.0.0\marc2016\common\implicit'

   dimension m(2)

   real,dimension(3)::coordin                      !定义坐标    

   integer,dimension(35354,2)::modee

c    

c   用来控制单元状态的子程序 

c   输入参数: 

c   M(1) 单元号 

c   M(2) 在自适应分析中为母单元号 

c   N 积分点号 

c   INC 增量步号 

c   TIME 增量步开始的时间 

c   TIMINC 时间增量 

c    

c   输出参数: 

c   MODE: 单元的死活状态 

c  =-1,定义死单元 

c  =1,定义活单元 

c  =2,保持单元状态不变 

c   IRSTSTR:等于1时表示重新设置单元应力为0  

c   IRSTSTN:等于1时表示重新设置单元应变为0  

c* * * * * 

cc  添加三个公共变量, 

cc  foreInc保存增量步 

cc  iopen文件打开标志 

cc  iend计算完成标志 

   common/check/foreInc,iopen,iend 

   data iopen,iend/0,0/ 

   real x0,y0,z0,x1,y1,z1,alpha,v,r,omega

c   (x0,y0,z0)为圆心位置,(x1,y1,z1)为热源中心位置,v为激光扫描线速度,r为扫描路径半径,omega为激光扫描角速度,alpha为参数方程参量

c   在0-19.5s阶段,即第一层熔覆过程,设置圆心位置为修复层上表面圆心,

c   在19.5-43.5s阶段,即第二层熔覆过程,设置圆心位置为修复层上表面圆心    

   integer::ie,mode,icode,kcus,nn !ie 为单元号,icode=0直接返回坐标,连续体单元kcus=1

   real::dist,dire !dist为遍历单元到热源中心距离,dire为数量积

   ie=m(1);

   if(ie.gt.25712.and.ie.lt.502035) return  !set直接跳过

   icode=0;kcus=1;nn=n

   call elmvar(icode,m,nn,kcus,coordin)                       

cc    

   if(time.le.19.5) then

   x0=175.54; y0=187.363;z0=-187.388

   else if (time.gt.19.5.and.time.le.43.5)then  

   x0=178.72;y0=190.471; z0=-185.311

   end if

c   设置激光扫描的线速度常数10,定义角速度omega

   v=10;omega=v/r;pi=3.1415926

c   设置激光扫描热源中心位置参数方程重要参量alpha

   if(time.le.13)then 

   r=19;alpha=omega*time

   else if (time.gt.13.and.time.le.19.5)then

   r=9;alpha=omega*time-13*omega

   else if(time.gt.19.5.and.time.le.35.5)then 

   r=24;alpha=omega*time-19.5*time

   else if (time.gt.35.5.and.time.le.43.5)then 

   r=12;alpha=omega*time-35.5*time

   end if

c   设置激光热源中心位置,假定热源在法线(1,1,1)的平面上运动

    x1=x0+(cos(alpha)-sin(alpha))*r/1.4142135

    y1=y0+cos(alpha)*r/1.4142135

    z1=z0+(cos(alpha)+sin(alpha))*r/1.73205081             热源位置     

cc

   dist=sqrt((coordin(1)-x1)**2+(coordin(2)-y1)**2

   $+(coordin(3)-z1)**2)                       积分点热源距离 

    dire=3.18*(175.54-coordin(1))+3.108*(187.363-coordin(2))

   $+2.077*(-187.388-coordin(3))                   数量积确定位置

    

c   初始激活第一层热源周围0.5mm的单元 ,死单元存入for96 

    if (inc.eq.0) then                          

     if(dist.le.0.5)then 

       if(dire.ge.0)then 

         mode=1

        else mode=-1

        end if

     else mode=-1

     end if

c  死单元初始化

   open(95,file='mode.txt',position='append')

   write(95,*)ie,mode

   close(95)

   go to 11

   end if

   open(95,file='mode.txt',status='old')

   do im=1,35454

     read(95,*) modee(im,1),modee(im,2)

   if(ie.eq.modee(im,1)) then

     mode=modee(im,2)

   end if 

   end do

   close (95)

      

     if(time+timinc.le.19.5)then 

       if(mode.eq.-1)then

         if(dist.le.11)then 

           if(dire.ge.0)then

             mode=1

           else mode=-1

           end if

         else mode=-1 

         end if

       else 

       return

        end if

        end if

   if(time+timinc.le.43.5.and.time+timinc.gt.19.5)then  

      if(mode.eq.-1)then

       if(dist.le.12)  then 

        mode=1

       else mode=-1;

       end if

            else mode=-1;

            end if

   else 

   return

        end if

c    一轮生死单元判断过后,更新mode.txt,并记录死单元

    open(95,file='mode.txt',status='old')

   close(95,status='delete')

c 删除原mode.txt文件,再重建更新

    open(95,file='mode.txt',status='new')

    do im=1,35454

      write(95,*) modee(im,1),modee(im,2)

            end do

    close(95)

    

c   

cc 

c   将当前增量步的死单元号写入文件 fort.96 中 

c   以便查看或者进行其他的处理 

    

  11 if(mode.eq.-1) then 

      write(96,*) 'deactivating element ', ie, ' increment ', inc 

   endif 

cc 

cc  新建一个过程文件 PostHide.proc 用来辅助后处理 

     if(iopen.eq.0) then 

      iopen=1 

      foreInc=inc 

      open(50,file='PostHide.proc',status='unknown') 

      close(50,status='delete') 

      open(50,file='PostHide.proc',status='new') 

      write(50,*)'*select_elements' 

   endif 

   if(iend.eq.0) then !判断是否到最后增量步 

    if(inc.eq.foreInc) then !判断增量步是否变化 

    if(mode.eq.-1) write(50,*) ie !写入当前增量步的死单元号 

    else 

    write(50,*)'#' !选择结束标志 

    write(50,*)'*invisible_selected' !使选中单元不可见 

    write(50,200) (inc-1) !显示第 (inc-1) 增量步 

 200  format('*post_skip_to',i5,/,'*select_elements') 

    write(50,*)'*animation_save' !保存当前窗口图形 

cc 

    if(mode.eq.-1) write(50,*) ie 

    foreInc=inc 

    endif 

    if(inc.eq.435) then !到最后一步,置 iend=1  

    iend=1 

    write(50,*)'#' 

    write(50,*)'*invisible_selected' 

    write(50,*)'*animation_save' 

    endif 

   endif 

cc  

c* * * * * 

   return 

   end 

代码尚未跑通,见笑了

邀请回答 我来回答

当前暂无回答

回答可获赠 200金币

没解决?试试专家一对一服务

换一批