这是我在这里的第一篇文章,我希望我能清楚地描述我与Abaqus subroutine
有关的问题。我是一个使用Fortran
的新手。基本上,我的目标是在开口横截面管上定义非均匀的表面热通量,我使用的是DFLUX subroutine
。作为开放的横截面,通量受到结构的自阴影的影响,并且必须相应地定义。显然,在每个积分点处调用子程序,因此不存储这些点的坐标,并且每次只有单个点的X,Y,Z值。我想做的是将所有坐标存储在一个阵列中,以便我可以比较不同的点来应用热通量的条件。我已经阅读了有关COMMON块或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
用户子程序提供了当前呼叫的元素编号,积分点编号和空间坐标。此信息可能用于存储(和访问)您需要的任何数据。数据存储/传输方法可以通过COMMON块,Fortran模块,甚至文本文件或其他一些外部“数据库”来完成。
>我推荐基于模块的方法。但是,请参阅this answer以获得有关如何使用COMMON块和模块的详细说明。
(编辑)为了完整性,一个带有模块和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
。
附注: