Abaqus DFLUX subroutine in Fortran

时间:2019-03-06 11:41:34

标签: fortran space subroutine abaqus

this is my first post here and I hope I will be clear describing the issues I'm having with Abaqus subroutine. I'm quite a newbie using Fortran. Basically, my goal is to define a non-uniform surface heat flux over an open cross-section tube and I'm using the DFLUX subroutine. Being open cross-section, the flux is influenced by the self-shadowing of the structure and has to be defined accordingly. Apparently the subroutine is called at each integration point, so that the coordinates of these points are not stored and I have each time just X,Y,Z values for a single point. What I'd like to do is to store all the coordinates in one array so that I can compare the different points to apply the conditions for the heat flux. I've read around about COMMON blocks or SAVE command, but I can't find how to use such options in my subroutine. I hope I've been clear enough. This is the subroutine I'm using:

     SUBROUTINE DFLUX(FLUX,SOL,JSTEP,JINC,TIME,NOEL,NPT,COORDS,JLTYP,
 1 TEMP,PRESS,SNAME)

  INCLUDE 'ABA_PARAM.INC'

   REAL X,Y,Z,t,pi,theta
   parameter(pi=3.1415)
   DIMENSION COORDS(3),FLUX(2),TIME(2)

   CHARACTER*80 SNAME

  X=COORDS(1)-0.1 ! X coordinate of the center in global ref
  Y=COORDS(2)+0.1732 ! Y coord of the center in global ref
  Z=COORDS(3)
  t=TIME(2)
  theta=atan2(X,Y)
  if (JSTEP.eq.1) then !Step with heat flux impinging on structure
  !flux dependant on the angle of incidence
      if (theta.ge.0 .and.theta.le.pi/2 .or. theta.le.-pi/2) then
       flux(1)=1400*abs(cos(theta))
       flux(2)=0
    else !shadowed portion of the structure
       flux(1)=0
       flux(2)=0
    endif
  else
     STOP
  endif
  RETURN

  END

1 个答案:

答案 0 :(得分:2)

背景:Abaqus提供了许多Fortran子例程“模板”(固定格式/ F77样式),允许用户在分析过程中获得特定信息或影响解决方案的某些方面,即用户子例程。 Abaqus控制何时调用用户子例程,传入/传出什么信息等。用户无法更改其中的任何内容,并且无法访问主程序或其专有源代码。但是,在用户子例程中,用户可以自由编写他们认为必要的任何有效代码。

在此问题中,OP希望存储每次对dflux用户子例程的调用中的信息,以便其他子例程或对dflux子例程的其他调用可用。注意:dflux没有提供此功能,因此OP需要解决方法。

可能的解决方法::幸运的是,dflux用户子例程提供了当前调用的元素编号,积分点编号和空间坐标。此信息可能可以用于存储(和访问)您需要的任何数据。数据存储/传输方法可以通过COMMON块,Fortran模块或什至文本文件或其他外部“数据库”来实现。

> 我推荐基于模块的方法。但是,请参见this answer,以获取有关如何同时使用COMMON块和模块的详细说明。

(EDIT)为完整起见,可以将一个带有模块和abaqus子例程的非常简单的示例构建为:

module data_mod
  ! Any routine may access this module with the statement: "USE data_mod".
  ! Any variable within the module is then shared by those routines.

  implicit none

  ! You can use an allocatable array, but for this example I will assume
  ! there are 1000 or fewer points, and up to 10 values for each.
  real, dimension(1000,10) :: point_data

end module data_mod


subroutine dflux(....all the args...)
  ! Note: you must "USE" modules before any other statements in the routine.

  use data_mod

  ! Now you may carry on with the rest of your code. 
  ! Be sure to have the required "INCLUDE 'ABA_PARAM.INC" statement,
  ! which defines how abaqus implements "IMPLICIT REAL" for your machine,
  ! and all of the boilerplate variable declarations included with the 
  ! DFLUX subroutine template.

  include 'aba_param.inc'
  (...etc...)

  ! For simplicity, I am assuming you have a unique ID for each point, and
  ! each ID is numerically equal to one of the row indices in 'point_data'.
  ! When ready to read/write data in the 'point_data' array:

  ! Read data:
  neighbor_vals(:) = point_data(NEIGHBOR_ID, 2:)
  old_data_at_current_point(:) = point_data(ID, 2:)

  (...etc...)

  ! Write data:
  point_data(ID,2:4) = coords(:)
  point_data(ID,5) = result1
  point_data(ID,6) = result2

end subroutine dflux

> 您将需要选择一种数据容器和一些巧妙的组织概念-也许使用元素编号,积分点编号或(x,y,z)坐标唯一地标识您要存储的数据。例如,一个简单的二维(MxN)数组可能就足够了:每一行代表第M 个积分点,第一列包含唯一的点标识符,其余列则包含任何您希望从每个点存储的值。注意:确定哪些点是“邻居”是您需要巧妙解决的另一个问题。完成此操作后,也许也可以将相邻点存储在数组中,以加快访问速度。

> 您可以从存储在数据容器中的其他集成点安全地读取数据,但不要写入/更改存储在数据容器中的值(无论是在COMMON块中还是在模块中) ),除非是针对当前正在调用dflux的当前集成点。


旁注:

  1. 新用户经常认为他们被困在Abaqus用户子例程中编写FORTRAN 77。 They aren't
  2. 将模块与abaqus用户子例程一起使用的最简单方法是将它们放在文件的顶部。然后,Abaqus将在运行分析时自动编译并链接它们。