Returns number of node incident in current contact incident.
Called By
CNFSUB and CFFSUB only.
Calling Sequence in FORTRAN
N_NODE_INCIDENTS (id, one_call_flag, num_incidents, errflag)
Function Prototype (C/C++)
void c_get_n_node_incidents(int id, int one_call_flag, int* num_incidents, int* errflag)
Input Argument
id | An integer variable specifying the ID of the corresponding CONTACT statement. |
one_call_flag | An integer value that specifies how many times CNFSUB/CFFSUB should called for node incidents. 0 - Call CNFSUB/CFFSUB once for each node in a contact incident. 1 - Call CNFSUB once for all nodes in a contact incident. 2 - Call CFFSUB once for all nodes in a contact incident. |
Output Argument
num_incidents | An integer variable specifying number of nodes in a contact incident. |
errflag | An integer variable that indicates if Adams successfully finds node incident data. If N_NODE_INCIDENTS detects an error, it sets errflag to a non-zero value. |
Extended Definition
The normal calling convention for CNFSUB and CFFSUB is to make one call to the user subroutines for each node in a contact incident. These are known as node incidents. When N_NODE_INCIDENTS is called from a CNSUB with one_call_flag set to 1, then, during simulation, there will be a single call to CNFSUB for all nodes in a contact incident. Likewise, when N_NODE_INCIDENTS is called from a CFSUB with one_call_flag set to 2, then, during simulation, there will be a single call to CFFSUB for all nodes in a contact incident. Data for all nodes can be obtained with the utility subroutine FLEX_CONTACT_DATA.
Example (FORTRAN)
SUBROUTINE CNFSUB(ID, TIME, PAR, NPAR, LOCI, NI, LOCJ, NJ,
& GAP, GAPDOT, GAPDOTDOT, AREA, DFLAG, IFLAG, FORCE_ARRAY)
C
C === Type and dimension statements ===================
IMPLICIT NONE
INTEGER ID
DOUBLE PRECISION TIME
DOUBLE PRECISION PAR(*)
INTEGER NPAR
DOUBLE PRECISION LOCI(3)
DOUBLE PRECISION NI(3)
DOUBLE PRECISION LOCJ(3)
DOUBLE PRECISION NJ(3)
DOUBLE PRECISION GAP
DOUBLE PRECISION GAPDOT
DOUBLE PRECISION GAPDOTDOT
DOUBLE PRECISION AREA
INTEGER DFLAG
INTEGER IFLAG
DOUBLE PRECISION FORCE_ARRAY(*)
C
INTEGER ARRAY_SIZE, I, ERRFLG, NODE_INCIDENTS, ONE_CALL
DOUBLE PRECISION K, C, E, D, VEC(200)
DOUBLE PRECISION FORCE(3)
COMMON /SFCOM/ K, C, E, D
DOUBLE PRECISION, ALLOCATABLE, TARGET :: LOCI_ARRAY(:)
DOUBLE PRECISION, ALLOCATABLE, TARGET :: LOCJ_ARRAY(:)
DOUBLE PRECISION, ALLOCATABLE :: GAP_ARRAY(:)
DOUBLE PRECISION, ALLOCATABLE :: GAPDOT_ARRAY(:)
DOUBLE PRECISION, POINTER :: PTR(:)
SAVE ARRAY_SIZE
SAVE LOCI_ARRAY, LOCJ_ARRAY, GAP_ARRAY, GAPDOT_ARRAY
C
C ===Executable code ==================================
C
C Initialize Contact parameters
IF (IFLAG .EQ. 1) THEN
K = PAR(1)
E = PAR(2)
C = PAR(3)
D = PAR(4)
C Allocate arrays with initial size of 100
ARRAY_SIZE = 100
PTR => LOCI_ARRAY
C Allocate memory for arrays
IF (.NOT. ASSOCIATED(PTR)) THEN
ALLOCATE(LOCI_ARRAY(3*ARRAY_SIZE))
ALLOCATE(LOCJ_ARRAY(3*ARRAY_SIZE))
ALLOCATE(GAP_ARRAY(ARRAY_SIZE))
ALLOCATE(GAPDOT_ARRAY(ARRAY_SIZE))
ENDIF
ENDIF
C Initialize incidents to zero
NODE_INCIDENTS = 0
C ONE_CALL = 1 tells Solver we want a single call to this Usersub C for all nodes in incident
ONE_CALL = 1
C Get number of nodes for this incident
CALL N_NODE_INCIDENTS(ID, ONE_CALL, NODE_INCIDENTS, ERRFLG)
IF ((ONE_CALL .EQ. 1) .AND. (NODE_INCIDENTS .GT. 0) .AND.
& (IFLAG .EQ. 0)) THEN
C Check number of nodes against Array size
IF (NODE_INCIDENTS .GT. ARRAY_SIZE) THEN
DEALLOCATE(LOCI_ARRAY)
DEALLOCATE(LOCJ_ARRAY)
DEALLOCATE(GAP_ARRAY)
DEALLOCATE(GAPDOT_ARRAY)
ALLOCATE(LOCI_ARRAY(3*NODE_INCIDENTS))
ALLOCATE(LOCJ_ARRAY(3*NODE_INCIDENTS))
ALLOCATE(GAP_ARRAY(NODE_INCIDENTS))
ALLOCATE(GAPDOT_ARRAY(NODE_INCIDENTS))
ARRAY_SIZE = NODE_INCIDENTS
ENDIF
C Get Array data
CALL FLEX_CONTACT_DATA(ID, 1, LOCI_ARRAY, ERRFLG)
CALL FLEX_CONTACT_DATA(ID, 2, LOCJ_ARRAY, ERRFLG)
CALL FLEX_CONTACT_DATA(ID, 5, GAP_ARRAY, ERRFLG)
CALL FLEX_CONTACT_DATA(ID, 6, GAPDOT_ARRAY, ERRFLG)
C Compute Normal Force at each node
DO I = 1, NODE_INCIDENTS
CALL IMPACT(GAP_ARRAY(I), GAPDOT_ARRAY(I), 0.0D0, K, E, C,
& D, 0, FORCE, ERRFLG)
CALL ERRMES(ERRFLG,'ERROR CALLING IMPACT',ID,'STOP')
FORCE_ARRAY(I) = FORCE(1)
END DO
ELSE
C Case of ONE_CALL=0 or no nodes in incident
CALL IMPACT(GAP, GAPDOT, 0.0D0, K, E, C, D, 0, FORCE, ERRFLG)
CALL ERRMES(ERRFLG,'ERROR CALLING IMPACT',ID,'STOP')
ENDIF
C Deallocate memory
IF (IFLAG .EQ. 5) THEN
PTR => LOCI_ARRAY
IF (ASSOCIATED(PTR)) THEN
DEALLOCATE(LOCI_ARRAY)
DEALLOCATE(LOCJ_ARRAY)
DEALLOCATE(GAP_ARRAY)
DEALLOCATE(GAPDOT_ARRAY)
ENDIF
ENDIF
RETURN
END