[1] 什么是 peridynamics ? 近场动力学,一种新起的非局部化模型;可用无网格法和有限元法求解,得到的结果需要后处理

[2] Paraview,一款可视化软件,可以将无网格法和有限元法求解得到的结果可视化,得到三维结构。

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

本文关注:用无网格法求解peridynamics,采用fortran语言在VS2013上编写,输出paraview所需要的.vtk文件,最后用paraview可视化

为了达到上述目的,需要完成以下几点:

1. 了解Paraview所需要的 .vtk文件是什么样的格式

2. 用fortran编写peridynamics模型的求解程序,将计算得到的坐标信息,位移,速度,损伤等以vtk格式保存

3. 用paraview 看看生成的vtk格式文件

文末附生成VTK文件的子程序,供大家参考使用。

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

本文算例:冲击有预先裂缝的薄板,来自试验

Kalthoff JF, Winkler S (1988) Failure mode transition at high rates of shear loading. In: Chiem
CY, Kunze H-D, Meyer LW (eds) Impact loading and dynamic behavior of materials, vol
1. DGM Informationsgesellschaft Verlag, Oberursel, pp 185–195

pcl 可视化 removeShape paraview可视化_ci

这是文献里面的结果:

pcl 可视化 removeShape paraview可视化_文件名_02

本文模拟得到的损伤云图:

pcl 可视化 removeShape paraview可视化_标量_03

 

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

1. 了解Paraview所需要的 .vtk文件是什么样的格式

 

 

 参考VTK格式官网:https://lorensen.github.io/VTKExamples/site/VTKFileFormats/

 本文只关注无网格,也就是只有粒子,没有cell等信息的一种,总结如下:

# vtk DataFile Version 3.0                     ----------- 第一行,表明vtk文件的版本,可以是3.0,4.0等;
title_Impact                                            ----------- 第二行,标题,随便取,自己好记
ASCII                                                     ----------- 第三行,数字格式,可以是ASCII或者二进制,我喜欢ASCII直白呀;二进制还得去转换,麻烦
DATASET UNSTRUCTURED_grid       ------------第四行,表明几何拓扑,可以去官网对应看一下,有总共五种;这种对于无网格的很好用
POINTS    n    float                                -------------第五行,点,点的数量,点坐标的格式,float浮点数

1x,1y, 1z                                                   

ix, iy,  iz                                                ------------- 这里是点的坐标,从第一个到第n个

nx,ny,nz

Point_data n                                       --------------- 这一行一定不能缺失,而且n要跟上头n一样,都等于节点的数量

SCALARS DAMAGE FLOAT 1          -------------- 记录点上的标量信息,比如损伤;SCALARS DAMAGE FLOAT 1 分别表示标量,标量的名字,自己取;

                                                                              标量的数字格式,float浮点数,后面的1不能少,不知道干啥的;
LOOKUP_TABLE DEFAULT              -------------  如果记录的是标量,这行一定要有,用来将标量映射为颜色云图;用默认的就行;

d1

di                                                       --------------- n个损伤标量信息,相应于n个节点

dn

VECTORS DISPLACEMENT FLOAT     ----------- 记录点上的矢量信息,这里是位移;

disp1x,disp1y, disp1z

dispix, dispiy,  dispiz                                ----------记录的n对位移矢量

dispnx, dispny, dispnz

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

2. 用fortran编写peridynamics模型的求解程序,将计算得到的坐标信息,位移,速度,损伤等以vtk格式保存

peridynamics 相关的理论参考 Silling教授的文章以及其他相关的。

用无网格法对peridynamics 求解后,可以得到以下信息:

材料点的坐标信息:coord(i,1), coord(i,2), coord(i,3),i从0到nodenumber(材料点总数);1,2,3分别代表x,y,z

材料点标量信息:损伤 dam(i,1); i表示材料点编号,1没啥信息,标量;当然还有其他标量比如压力,温度等;

材料点的矢量信息:位移disp(i,1), disp(i,2), disp(i,3); 速度 vel(i,1), vel(i,2), vel(i,3);  i同样是材料点的编号,1,2,3表示x,y,z

求解是按照时间步推进的,每一个时间下,都会得到以上所有信息,我们需要每一个时间步都记录下以上所有信息,每一个时间步对应一个vtk文档,

不同时间步对应的vtk文档的命名采用数字递增,这样在paraview中就可以识别到一个vtk群组,可形成动画效果。      

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

                                                                                                 fortran 代码:

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

implicit none

% 申明变量

integer:: i,j,k,tt,nt = 2000

character(len=100):: fileDir,fileName,fileSeq,fileSuffix,myStr
integer::counterLen = 4
logical::FEXIST

    fileDir = 'D:\0923\'                     % fileDir 表示文件路径;这里是  d盘下面的0923文件夹;后续生成的.vtk文件都会保存在这里
    inquire(file = trim(fileDir),EXIST=FEXIST)     % 看看该文件夹是否已经存在
    
    if(.not.FEXIST) then                   %  如果没有,就系统创建一个
    call system('md '//trim(fileDir))    %
    endif

 Do k=tt, nt     ! 注释 nt是总的时间步,例如2000步,根据对peridynamics的求解需要

    fileName = 'view'           % 文件名 为 view
    fileSuffix = '.vtk'             % 文件后缀为 .vtk
    write(myStr,'(I2)')counterLen    %  参数counterLen 是用来连续命名.vtk文件的,这里取 counterLen等于4,意味着最大将生成 9999个文件;若取为3,则只能生成999个;

counterLen应该根据总时间步nt来确定;  counterLen等于4,第一、二个文件是 view0001.vtk; view0002.vtk
    myStr = '(I'//trim(adjustl(myStr))//')'  % myStr决定文件名后面的是0001还是0002;
    write(fileSeq,myStr)tt                       % 这样文件名后面就是tt了,也就是当前时间步;比如当前时间步为第100,也就是tt=100;那么对应的vtk文件就是 view0100.vtk

    do j = 1,counterLen - len(trim(adjustl(fileSeq)))
    fileSeq = '0'//adjustl(trim(fileSeq))
    enddo
    open(tt+50,file = adjustl(trim(fileDir))//adjustl(trim(fileName))&    
    &//adjustl(trim(fileSeq))//adjustl(trim(fileSuffix)))    % 打开该生成的文件,准备写入了;

DATASET UNSTRUCTURED_grid 对应于只有材料点                  
      write(tt+50,169)     %% 写入  'POINTS',3x,'20000',3x,'float'  

   do i = 1, totnode
         write(tt+50,170) coord(i,1), coord(i,2), coord(i,3)             %% 写入点的坐标信息
   end do      
      write(tt+50,171)                                %% 写入这句话  'point_data',3x,'20000',/,'SCALARS Damage FLOAT 1',/,'LOOKUP_TABLE DEFAULT'    / 表示换行
   do i = 1, totnode
         write(tt+50,172) dmg(i,1)               %% 写入 每个点的损伤信息
   end do
      write(tt+50,173)                                  %% 写入 这句话 'VECTORS Displacement FLOAT'
   do i = 1, totnode
         write(tt+50,170) disp(i,1), disp(i,2), disp(i,3)     %% 写入 点的位移矢量信息
   end do  
      write(tt+50,174)                                   %%  写入这句话'VECTORS Velocity FLOAT'
   do i = 1, totnode
         write(tt+50,170) vel(i,1), vel(i,2), vel(i,3)     %% 写入每个点的速度信息
   end do
   
   close(tt+50)
    
end do 

168 format('# vtk DataFile Version 3.0', / ,'title_impact', /, 'ASCII', /, 'DATASET UNSTRUCTURED_grid')     %% 3x表示空三个位置;/表示换行;
169 format('POINTS',3x,'182709',3x,'float')
170 format(e12.5,3x,e12.5,3x,e12.5)
171 format('point_data',3x,'182709',/,'SCALARS Damage FLOAT 1',/,'LOOKUP_TABLE DEFAULT')
172 format(e12.5)
173 format('VECTORS Displacement FLOAT')
174 format('VECTORS Velocity FLOAT')

 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$  

                                   附生成的vtk格式文档压缩包

百度网盘链接:https://pan.baidu.com/s/1PjiJDZuRLH6i3u5gSkD9Cw
提取码:0104

整个有1350个文件,每个10M左右,太大了,因此我只放了最后的大概10个

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

                                                                                              3. 用paraview 看看生成的vtk格式文件

1.  用paraview打开生成的vtk文件;因为生成的VTK文件是连续编号的,paraview自动识别为组群。点击最上头的view...vtk 即可

pcl 可视化 removeShape paraview可视化_文件名_04

2. 点击apply,把surface改为point gaussian ,因为我们的是点,没有cell;

pcl 可视化 removeShape paraview可视化_标量_05

   

pcl 可视化 removeShape paraview可视化_ci_06

3. 就可以看到点构成的结构啦。

pcl 可视化 removeShape paraview可视化_文件名_07

4. 我这里主要想看损伤。点击左边选择 damage;点击edit,会出来右边,可以调节范围;在 rescale那里,选择 clamp  and update every time step ;

点击右上角的小x,关掉右边的这一栏;

pcl 可视化 removeShape paraview可视化_标量_08

5. 这里可以播放,可以选择要显示的时间步。

pcl 可视化 removeShape paraview可视化_文件名_09

 

6. 我们看看最后的效果吧

pcl 可视化 removeShape paraview可视化_标量_03

四、生成.VTK文件的子程序

! subroutine to output data to paraview readable vtk format
! 
subroutine output_to_paraview_vtk(itimestep, x, vx, dis,dvx, mass, rho, p, u, c, itype, hsml, ntotal, mark,tots)
        
        use parameter
        implicit none
        character(len=100):: fileDir,fileName,fileSeq,fileSuffix,myStr
        integer::counterLen = 6
        logical::FEXIST
        integer:: i, j, itimestep,ntotal, itype(maxn), nvirt, mark(maxn)
        double precision x(3, maxn), vx(3, maxn), dvx(3, maxn), dis(3, maxn),mass(maxn), rho(maxn), p(maxn), u(maxn), hsml(maxn), c(maxn),pforce(maxn,3),tots(maxn,3,3)

        fileDir = 'D:\PD-SPH-paraview\'
!        inquire(file = trim(fileDir),EXIST=FEXIST)
    
!        if(.not.FEXIST) then
!        call system('md '//trim(fileDir))
!        end if
        
        fileName = 'view'
        fileSuffix = '.vtk'
        write(myStr,'(I2)')counterLen
        myStr = '(I'//trim(adjustl(myStr))//')'
        write(fileSeq,myStr)itimestep

        do j = 1,counterLen - len(trim(adjustl(fileSeq)))
           fileSeq = '0'//adjustl(trim(fileSeq))
        end do
        
        open(itimestep+50,file = adjustl(trim(fileDir))//adjustl(trim(fileName))&
                   &//adjustl(trim(fileSeq))//adjustl(trim(fileSuffix)))     
        
    ! vtk inofrmation    
        write(itimestep+50,168)
         
    ! particle position                           
          write(itimestep+50,169)              
         do i = 1, ntotal
             if(abs(itype(i)).ne.3) then
              if (dim .eq. 1) then
                write (itimestep+50, 170) x(1, i), 0.0, 0.0
              else if (dim .eq. 2) then
                write (itimestep+50, 170) x(1, i), x(2, i), 0.0
              else if (dim .eq. 3) then
                write (itimestep+50, 170) x(1, i), x(2, i), x(3, i)
              end if
             end if
         end do
         
    ! particle  mass
        write(itimestep+50,171)
         do i = 1, ntotal
             if(abs(itype(i)).ne.3) then
              write (itimestep+50, 172) mass(i)
              end if
         end do

    ! particle  density
        write(itimestep+50,173)
         do i = 1, ntotal
             if(abs(itype(i)).ne.3) then
              write (itimestep+50, 172) rho(i)
              end if
         end do

    ! particle  pressure
        write(itimestep+50,174)
         do i = 1, ntotal
             if(abs(itype(i)).ne.3) then
              write (itimestep+50, 172) p(i)
             end if
         end do                      

    ! particle  particle_type
        write(itimestep+50,178)
         do i = 1, ntotal
             if(abs(itype(i)).ne.3) then
              write (itimestep+50, 180) itype(i)
             end if
         end do

    ! particle  smooth_length
        write(itimestep+50,179)
         do i = 1, ntotal
             if(abs(itype(i)).ne.3) then
              write (itimestep+50, 172) hsml(i)
             end if
         end do
                  
    168 format('# vtk DataFile Version 3.0', / ,'title_impact', /, 'ASCII', /, 'DATASET UNSTRUCTURED_grid')
    169 format('POINTS',3x,'584808',3x,'float')
    170 format(e12.5,3x,e12.5,3x,e12.5)
    171 format('point_data',3x,'584808',/,'SCALARS mass FLOAT 1',/,'LOOKUP_TABLE DEFAULT')
    172 format(e12.5)
    180 format(I5)
    173 format('SCALARS density FLOAT 1',/,'LOOKUP_TABLE DEFAULT')
    174 format('SCALARS pressure FLOAT 1',/,'LOOKUP_TABLE DEFAULT')
    175 format('SCALARS energy FLOAT 1',/,'LOOKUP_TABLE DEFAULT')    
    176 format('VECTORS Velocity FLOAT')
    177 format('VECTORS Acceleration FLOAT')    
    178 format('SCALARS particle_type FLOAT 1',/,'LOOKUP_TABLE DEFAULT')    
    179 format('SCALARS smooth_length FLOAT 1',/,'LOOKUP_TABLE DEFAULT')

    close(itimestep+50) 
     
 end