Hi,
I am recently trying to read data from external files into ABAQUS by subroutines like USDFLD, which will finally be used to modify material behavior in UMAT. However, when I code with Fortran in USDFLD, I encounter some strange issues:
- Writing seems not a problem, but reading with Read(10,*, IOSTAT = IOS) VALUE, for example, will lead to the following issue if I want to use IOS as an identifier for the end of the file: forrtl: severe (24): end-of-file during read. I solve it by adding another dummy line of data at the end of the file, but I am wondering why the way with IOS does not work since I also tried the same code outside ABAQUS with the same Fortran compiler and it works quite well.
In the USDFLD as shown below, I try to read data into vectors and strings I define in the subroutine. However, it seems that I always need to do something like WRITE(*,*) 'NO MORE WAITING' to carry on the simulation, otherwise I will get stuck after finishing the first increment in the first step, which can be seen from the .sta file. I feel this has something to do with flushing the buffer since writing to default file (.log) includes the flushing, but I still do not know the reason for this.
Thank you!
SUBROUTINE USDFLD(FIELD, STATEV, PNEWDT, DIRECT, T, CELENT, 1 TIME, DTIME, CMNAME, ORNAME, NFIELD, NSTATV, NOEL, NPT, LAYER, 2 KSPT, KSTEP, KINC, NDI, NSHR, COORD, JMAC, JMATYP, MATLAYO, LACCFLA) C INCLUDE 'ABA_PARAM.INC' C CHARACTER*80 CMNAME, ORNAME DIMENSION FIELD(NFIELD), STATEV(NSTATV), DIRECT(3,3), T(3,3), TIME(2) DIMENSION ARRAY(15), JARRAY(15), JMAC(*), JMATYP(*), COORD(*) C Variables for moisture fields at the start and end of the step REAL*8 STEPT, MOISTA, MOIEND, MOIINT INTEGER IOS, NUMVAL, ITER, ITETOT REAL MOFDST(100), MOFDEN(100), XX(100) CHARACTER*100 MOIFIL, STAFIL, UPDSTA MOIFIL = '/home/youwang/Desktop/HT-FEM/moisture_data.csv' STAFIL = '/home/youwang/Desktop/HT-FEM/update_state_delphin.txt' IF (KINC .EQ. 1) THEN C Loop to check if the moisture data file is ready ITETOT = 0 3000 ITER = 0 3001 ITER = ITER + 1 IF (ITER .GT. 1000) THEN OPEN(16, FILE=STAFIL, STATUS='OLD') READ(16,*) UPDSTA CLOSE(16) IF (UPDSTA .EQ. 'READY') THEN OPEN(18, FILE=MOIFIL, STATUS='OLD') NUMVAL = 0 1001 CONTINUE NUMVAL = NUMVAL + 1 READ(18,*,IOSTAT=IOS) XX(NUMVAL), MOFDST(NUMVAL), MOFDEN(NUMVAL) IF (XX(NUMVAL) .EQ. 111) THEN NUMVAL = NUMVAL - 1 GO TO 2000 END IF GO TO 1001 2000 CLOSE(18) GO TO 2001 ! Exit loop if data is successfully read END IF ITETOT = ITETOT + 1 IF (ITETOT .GT. 5) THEN WRITE(*,*) 'NO MORE WAITING' GO TO 2001 END IF GO TO 3000 ELSE GO TO 3001 END IF C In the first increment, access the step duration (e.g., from FIELD(3)) and read the moisture data 2001 STEPT = FIELD(3) ! Access passed step duration from Python STATEV(2) = STEPT ! Store step duration in STATEV(2) ELSE C Retrieve the stored step duration from STATEV for other increments STEPT = STATEV(2) END IF C update the STAFIL at the end of the step IF (KINC .EQ. 1) THEN OPEN(17, FILE=STAFIL, STATUS='UNKNOWN') WRITE(17,*) 'NOTREADY' CLOSE(17) END IF C Interpolate moisture values spatially DO 300, I = 1, NUMVAL - 1 IF (COORD(1) .GT. XX(I) .AND. COORD(1) .LT. XX(I+1)) THEN MOISTA = MOFDST(I) + (MOFDST(I+1) - MOFDST(I)) * (COORD(1) - XX(I)) / (XX(I+1) - XX(I)) MOIEND = MOFDEN(I) + (MOFDEN(I+1) - MOFDEN(I)) * (COORD(1) - XX(I)) / (XX(I+1) - XX(I)) GO TO 300 ELSE IF (COORD(1) .LT. XX(1)) THEN MOISTA = MOFDST(1) MOIEND = MOFDEN(1) GO TO 300 ELSE MOISTA = MOFDST(NUMVAL) MOIEND = MOFDEN(NUMVAL) GO TO 300 END IF END IF 300 CONTINUE C Linearly interpolate between start and end moisture values MOIINT = MOISTA + (MOIEND - MOISTA) * (TIME(1) / STEPT) C Assign the interpolated moisture value back to FIELD for this time increment FIELD(1) = MOIINT C Update the state variables STATEV(1) = MOIINT END
