N_NODE_INCIDENTS

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