简体   繁体   English

Fortran 中的 Abaqus DFLUX 子程序

[英]Abaqus DFLUX subroutine in Fortran

this is my first post here and I hope I will be clear describing the issues I'm having with Abaqus subroutine .这是我在这里的第一篇文章,我希望我能清楚地描述我在使用Abaqus subroutine遇到的问题。 I'm quite a newbie using Fortran .我是一个使用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 .基本上,我的目标是在开口横截面管上定义非均匀表面热通量,我正在使用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.显然,在每个积分点都会调用子程序,因此不会存储这些点的坐标,而且我每次只有单个点的 X、Y、Z 值。 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.我已经阅读了有关 COMMON 块或 SAVE 命令的内容,但是我找不到如何在我的子例程中使用这些选项。 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

background: Abaqus provides a number of Fortran subroutine "templates" (in fixed-format/F77 style) that allow users to get specific info or influence certain aspects of the solution during an analysis, aka user-subroutines.背景: Abaqus 提供了许多 Fortran 子程序“模板”(固定格式/F77 样式),允许用户在分析过程中获取特定信息或影响解决方案的某些方面,也就是用户子程序。 Abaqus controls when the user-subroutines are called, what info is passed in/out, etc. Users cannot change any of that, and have no access to the main program or its proprietary source code. Abaqus 控制何时调用用户子程序、传入/传出什么信息等。用户不能更改任何这些,也无法访问主程序或其专有源代码。 However, within a user-subroutine, the user is free to write any valid code they feel is necessary.但是,在用户子程序中,用户可以自由编写他们认为必要的任何有效代码。

In this question, the OP wants to store information from each call to the dflux user-subroutine so that it is available to other subroutines or to other calls to the dflux subroutine.在这个问题中,OP 希望存储来自对dflux用户子例程的每次调用的信息,以便其他子例程或对dflux子例程的其他调用可以使用这些dflux Note: this capability is not provided by dflux , so the OP needs a work-around.注意:此功能不是由dflux提供的,因此 OP 需要一种解决方法。

possible work-arounds: Luckily, the dflux user-subroutine provides the element number, the integration point number, and the spatial coords for the current call.可能的变通方法:幸运的是, dflux用户子例程提供了当前调用的元素编号、积分点编号和空间坐标。 This info can probably be used to store (and access) any data you need.此信息可能可用于存储(和访问)您需要的任何数据。 The data storage/transfer method might be accomplished through a COMMON block, a Fortran module, or even a text file or some other external "database".数据存储/传输方法可以通过 COMMON 块、Fortran 模块,甚至文本文件或其他一些外部“数据库”来完成。

> I recommend the module-based approach. >我推荐基于模块的方法。 However, see this answer for a good explanation of how to use both COMMON blocks and modules.但是,有关如何使用 COMMON 块和模块的很好解释,请参阅此答案

(EDIT) For completeness, a very simple example with a module and an abaqus subroutine could be structured something like: (编辑)为了完整起见,一个带有模块和 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

> You will need to choose a type of data container and some clever organizational concept - perhaps using the element number, integration point number, or the (x,y,z) coordinates to uniquely identify the data you want to store. >您需要选择一种类型的数据容器和一些巧妙的组织概念——可能使用元素编号、积分点编号或 (x,y,z) 坐标来唯一标识您要存储的数据。 For instance, a simple 2-dimensional (MxN) array might be sufficient: each row represents the M th integration point, the first column contains the unique point identifier(s), and the remaining columns contain any values you want to store from each point.例如,一个简单的二维 (MxN) 数组可能就足够了:每一行代表第 M积分点,第一列包含唯一的点标识符,其余列包含您想要从每个积分点存储的任何值。观点。 Note: Determining which points are "neighbors" is another topic you will need a clever solution for.注意:确定哪些点是“邻居”是另一个需要巧妙解决方案的主题。 Once you've done this, perhaps neighboring points can be stored in the array as well, for faster access.完成此操作后,也许相邻点也可以存储在阵列中,以便更快地访问。

> You are safe reading data from other integration points stored in the data container, but do not write/change the values stored in the data container (whether it is within a COMMON block or a module) unless it is for the current integration point where dflux is currently being called. >您可以安全地从数据容器中存储的其他集成点读取数据,但不要写入/更改数据容器中存储的值(无论是在 COMMON 块内还是模块内),除非是针对当前集成点当前正在调用dflux


side notes:边注:

  1. New users often think they are stuck writing FORTRAN 77 in their Abaqus user-subroutines.新用户通常认为他们在他们的 Abaqus 用户子例程中编写 FORTRAN 77 很困难。 They aren't .他们不是
  2. The easiest way to use modules along with abaqus user-subroutines is to place them at the top of your file.将模块与 abaqus 用户子程序一起使用的最简单方法是将它们放在文件的顶部。 Abaqus will then compile and link them automatically when you run the analysis.然后,当您运行分析时,Abaqus 将自动编译和链接它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM