Product: Abaqus/Explicit
User subroutine VEXTERNALDB:
is called once at the beginning of the analysis, at the beginning of each step, before each increment, at the start of each increment, at the end of each increment, at the end of each step, and finally at the end of the analysis;
can be used to communicate data between external programs and user subroutines within Abaqus/Explicit;
can be used to control the time incrementation of the Abaqus/Explicit analysis;
can be used to control the output of the restart data for the analysis;
can be used either to skip the remainder of an Abaqus step or to terminate the analysis;
can be used to open and close external files as needed for exchange of data with the Abaqus analysis;
can be used to exchange data with other user subroutines via user-allocated global and thread-local arrays (see “Allocatable arrays,” Section 2.1.23) and;
can be used to exchange data with other Abaqus processes via an MPI mechanism (see “Obtaining parallel processes information,” Section 2.1.4) in domain-parallel analyses.
Typically, Abaqus user subroutines are called with the context data limited to a specific material point, a specific element, etc. Rarely, you need to know some nonlocal information such as the state of the neighboring material points or elements. In other situations you want to specify the behavior in the user subroutines to depend dynamically on the external programs. Both these complex scenarios can be addressed using user subroutine VEXTERNALDB.
VEXTERNALDB is called once at the beginning of the analysis, at the beginning of each step, before each increment, at the start of each increment, at the end of each increment, at the end of each step, and finally at the end of the analysis. Other Abaqus subroutines are called after the call to user subroutine VEXTERNALDB at the start of the increment but before the next call at the end of that increment.
subroutine vexternaldb(lOp, i_Array, niArray, r_Array, nrArray) C include 'vaba_param.inc' c C Contents of i_Array parameter( i_int_nTotalNodes = 1, * i_int_nTotalElements = 2, * i_int_kStep = 3, * i_int_kInc = 4, * i_int_iStatus = 5, * i_int_lWriteRestart = 6 ) C Possible values for the lOp argument parameter( j_int_StartAnalysis = 0, * j_int_StartStep = 1, * j_int_SetupIncrement = 2, * j_int_StartIncrement = 3, * j_int_EndIncrement = 4, * j_int_EndStep = 5, * j_int_EndAnalysis = 6 ) C Possible values for i_Array(i_int_iStatus) parameter( j_int_Continue = 0, * j_int_TerminateStep = 1, * j_int_TerminateAnalysis = 2) C Contents of r_Array parameter( i_flt_TotalTime = 1, * i_flt_StepTime = 2, * i_flt_dTime = 3 ) C dimension i_Array(niArray), * r_Array(nrArray) kStep = i_Array(i_int_kStep) kInc = i_Array(i_int_kInc) Note that you can use the MPI communication between parallel Abaqus processes to gather and scatter the data. C Start of the analysis if (lOp .eq. j_int_StartAnalysis) then User coding to set up the environment, open files, launch/connect to the external programs, etc. C continuation from a previous analysis (restart) if (kStep .ne. 0) then end if C Start of the step else if (lOp .eq. j_int_StartStep) then Set up or exchange (import and export) initial values with external programs. C The initial values may need to match those at the point of restart. if ( kInc .ne. 0) then end if C Setup the increment else if (lOp .eq. j_int_SetupIncrement) then Change i_Array(i_int_lWriteRestart) and i_Array(i_int_iStatus) if desired. Change r_Array(i_flt_dTime) if desired. C Start of the increment else if (lOp .eq. j_int_StartIncrement) then The time increment is finalized. Use r_Array(i_flt_dTime) if desired. If needed, gather and export data from the configuration at the end of the previous increment to external programs. Import and scatter data from external program to influence the current Abaqus increment. C End of the increment else if (lOp .eq. j_int_EndIncrement) then Change i_Array(i_int_iStatus) if desired. Gather and export data from the configuration at the end of the current increment to external programs. C End of the step else if (lOp .eq. j_int_EndStep) then In the case of multiple steps, prepare the transition to the next step. For example, these data can serve as initial values for the next step. C End of the analysis else if (lOp .eq. j_int_EndAnalysis) then User coding to close files and disconnect any external programs, etc. end if return end
i_Array(i_int_lWriteRestart)
i_Array(i_int_lWriteRestart) indicates whether restart data are currently scheduled to be written. When lOp=j_int_SetupIncrement, you can optionally modify it either to write restart data or to skip it. A value of 1 would capture the data for a possible future restart of the analysis from the current time point; whereas 0 would forego such restart from the current time point.
i_Array(i_int_iStatus)
i_Array(i_int_iStatus) indicates the status of the analysis and has a default value of j_int_Continue. When lOp=j_int_SetupIncrement or j_int_EndIncrement, you can optionally modify it either to a value of j_int_TerminateStep to skip the remainder of the current step or to a value of j_int_TerminateAnalysis to terminate the analysis. If you request to terminate the analysis, the analysis will go through one additional increment with a zero time increment size to generate the field output that reflects the state at termination, as described in “Abaqus/Explicit output as a result of analysis termination” in “Output to the output database,” Section 4.1.3 of the Abaqus Analysis User's Guide. When the passed in value is not equal to j_int_Continue, you can coordinate the necessary events with any external program.
r_Array(i_flt_dTime)
Time increment. When lOp=j_int_SetupIncrement, it is the time increment proposed for the current increment and it can be modified to control the incrementation. When lOp=j_int_StartIncrement, it is the finalized time increment for the increment to be taken; whereas when lOp=j_int_EndIncrement, it is the time increment just taken.
i_Array(i_int_nTotalNodes)
Total number of nodes in the model.
i_Array(i_int_nTotalElements)
Total number of elements in the model.
i_Array(i_int_kStep)
Current step number. When lOp=j_int_StartAnalysis, i_Array(i_int_kStep) gives the restart step number.
i_Array(i_int_kInc)
Current increment number. When lOp=j_int_StartStep, i_Array(i_int_kInc) gives the restart increment number.
lOp
lOp=j_int_StartAnalysis indicates that the user subroutine is being called at the start of the analysis. A nonzero i_Array(i_int_kStep) indicates that the analysis is starting from a prior analysis (restart).
lOp=j_int_StartStep indicates that the user subroutine is being called at the start of a step. A nonzero i_Array(i_int_kInc) indicates a continuation of the step from a prior analysis (restart).
lOp=j_int_SetupIncrement indicates that the user subroutine is being called to set up an increment and r_Array(i_flt_dTime) can be modified. In addition, i_Array(i_int_lWriteRestart) can be modified to control output of restart data at the end of the current increment. You can also control the continuation of the analysis via i_Array(i_int_iStatus).
lOp=j_int_StartIncrement indicates that the user subroutine is being called at the start of the agreed increment. You need to import or compute the data necessary for starting the increment.
lOp=j_int_EndIncrement indicates that the user subroutine is being called at the end of the increment. If you have results to export, this is a good time to do so. You can also control the continuation of the analysis via i_Array(i_int_iStatus).
lOp=j_int_EndStep indicates that the user subroutine is being called at the end of the step.
lOp=j_int_EndAnalysis indicates that the user subroutine is being called at the end of the analysis.
r_Array(i_flt_StepTime)
Value of current step time. When lOp=j_int_SetupIncrement or j_int_StartIncrement, the step time is at the start of the increment. When lOp =j_int_EndIncrement, the step time is at the end of the increment.
r_Array(i_flt_TotalTime)
Value of current total time. When lOp =j_int_SetupIncrement or j_int_StartIncrement, the total time is at the start of the increment. When lOp =j_int_EndIncrement, the total time is at the end of the increment.