Fortran语言中的Abaqus DFLUX子程序
这是我在这里的第一篇文章,我希望我能清楚地描述我在使用Fortran语言中的Abaqus DFLUX子程序,fortran,space,subroutine,abaqus,Fortran,Space,Subroutine,Abaqus,这是我在这里的第一篇文章,我希望我能清楚地描述我在使用Abaqus子例程时遇到的问题。我是一个使用Fortran的新手。基本上,我的目标是定义开放横截面管道上的非均匀表面热流,我正在使用DFLUX子例程。 由于是开放的横截面,通量受到结构自阴影的影响,因此必须进行相应的定义。 显然,在每个积分点调用子例程,这样就不会存储这些点的坐标,并且每次只有单个点的X,Y,Z值。我想做的是将所有坐标存储在一个数组中,这样我就可以比较不同的点来应用热流的条件。 我已经阅读了有关公共块或SAVE命令的内容,但在
Abaqus子例程时遇到的问题。我是一个使用Fortran的新手。基本上,我的目标是定义开放横截面管道上的非均匀表面热流,我正在使用DFLUX子例程
。
由于是开放的横截面,通量受到结构自阴影的影响,因此必须进行相应的定义。
显然,在每个积分点调用子例程,这样就不会存储这些点的坐标,并且每次只有单个点的X,Y,Z值。我想做的是将所有坐标存储在一个数组中,这样我就可以比较不同的点来应用热流的条件。
我已经阅读了有关公共块或SAVE命令的内容,但在我的子例程中找不到如何使用这些选项。
我希望我已经够清楚了。
这是我正在使用的子程序:
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
背景:Abaqus提供了大量Fortran子程序“模板”(固定格式/F77样式),允许用户在分析过程中获取特定信息或影响解决方案的某些方面,也称为用户子程序。Abaqus控制何时调用用户子例程、传入/传出什么信息等。用户无法更改这些信息,也无法访问主程序或其专有源代码。但是,在用户子例程中,用户可以自由编写他们认为必要的任何有效代码
在这个问题中,OP希望存储对dflux
用户子例程的每次调用的信息,以便其他子例程或对dflux
子例程的其他调用可以使用。注意:dflux
不提供此功能,因此OP需要解决此问题
可能的解决方法:幸运的是,dflux
用户子例程为当前调用提供元素编号、积分点编号和空间坐标。此信息可能用于存储(和访问)您需要的任何数据。数据存储/传输方法可以通过公共块、Fortran模块、甚至文本文件或其他外部“数据库”来实现
我推荐基于模块的方法。但是,有关如何使用公共块和模块的详细说明,请参见
(编辑)为了完整起见,一个带有模块和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个集成点,第一列包含唯一的点标识符,其余列包含要从每个点存储的任何值。注意:确定哪些点是“邻居”是另一个需要聪明解决的问题。完成此操作后,可能还可以将相邻点存储在阵列中,以便更快地访问
您可以安全地从存储在数据容器中的其他集成点读取数据,但不要写入/更改存储在数据容器中的值(无论是在公共块还是模块中),除非是当前正在调用dflux
的当前集成点
旁注:
新用户经常认为他们无法在Abaqus用户子程序中编写FORTRAN 77李>
将模块与abaqus用户子例程一起使用的最简单方法是将它们放在文件的顶部。然后,当您运行分析时,Abaqus将自动编译并链接它们。
首先,欢迎来到StackOverflow。根据社区的建议,建议包含格式化的源代码,以帮助人们理解您的问题。请检查文档好的,我已经添加了子程序,谢谢你的建议!不用谢,我很乐意帮助新手更好地描述问题并找到解决方案。希望你能找到一个好答案。我想我们还需要你起诉子程序的代码。不只是调用本身,还包括上下文,以查看如何比较其他点。Abaqus的输入文件相当长,因为它包含FEM模型的所有节点!我应该附加它吗?谢谢Matt,我对基于模块的方法还有一些问题。在子程序顶部的模块中,我是否应该声明一个二维数组(可能是可分配的?),在该数组中定义dflux变量的位置,并将该数组存储在公共块中?我如何从子程序访问存储的数据?我仍然很困惑。@Gianluca我添加了一些示例代码,您可以使用这些代码开始学习。另外,请注意,2D数组(可分配或不可分配)被认为是一个非常简单的数据容器,可以工作。您可能会发现其他更适合您的需求(如用户定义的类型等)。在任何情况下,使用模块将允许您在子例程之间存储/传输/共享数据(没有公共块)。您的回答非常有用,我最终成功地将所需坐标保存在矩阵中。现在我正试图找到一种方便的方法来使用我存储的热流数据。我注意到,对于每一个增量,子例程的调用次数都是积分点数的数倍。我期待着一个相等的数字。基本上我想先填充矩阵,当矩阵中没有更多的零时,应用通量的条件。我现在正在努力实现这一点@吉安卢卡,太好了。顺便说一句,大多数子例程在每次增量期间被调用多次;)例如:调用#1初始化数据,调用#2初始化ca