UCOSUB

The UCOSUB evaluation subroutine computes a constraint value and its derivatives for a UCON statement (f77). You must write a UCOSUB whenever one or more UCON statements are used in a dataset.
 
Note:  
Use mixed case names for the Adams subroutine names when using the C style interface. For the default subroutine name capitalize the first letter and have the remaining letters lower case. Doing this ensures that Adams Solver correctly distinguishes a C style subroutine from Fortran and calls with the appropriate interface.

Use

Corresponding Statement

UCON/id, FUNCTION=USER(r1[,...,r30])  
 
[ ] Optionally select the item.

Calling Sequence

SUBROUTINE UCOSUB (id, time, q, par, npar, idrsel,
& iflag, scalar, array, xmatrx)

Input Arguments

 
id
An integer variable that contains the ID of the UCON statement requesting information from UCOSUB. From the identifier, Adams Solver automatically knows other information (such as the par argument) available in the corresponding statement.
time
A double-precision variable through which Adams Solver conveys the current simulation time.
q
A double-precision array (of as many as thirty elements) that contains the current values of the part principal axes variables. These values are in the order specified by the call to UCOVAR.
par
A double-precision array of constants taken in order from the USER parenthetical list of the UCON statement; r1[,...,r30].
npar
An integer variable that indicates the number of constants specified in the USER parenthetical list. The primary purpose of npar is to provide UCOSUB with the number of values stored in the par array.
idrsel
A three-element integer array containing control values for returning the proper information through scalar, array, and xmatrx.
iflag
An integer variable that Adams Solver sets to indicate why the routine is being called:
When iflag is 0 Adams Solver calling to compute the value of the user-written variable. When iflag is set to 3 call UCOVAR for initial definition of the principal axes variables and do any initializations that your subroutine requires.
When your user-defined subroutine has static data that needs to be saved and restored to support the Adams Solver commands Save and Reload, then call the serialization functions for your data when iflag is set to 7, and the un-serialization functions when iflag is set to 9.
Note: In simple subroutines where serializing data is not needed, you can declare iflag as a logical variable. In this case you can do any initializations when Adams Solver sets iflag to true, and compute the subroutine's value when Adams Solver sets iflag to false.

Output Arguments

 
array
A thirty-element double-precision array that returns to Adams Solver the first derivatives of the constraint relationship with respect to the principal axes variables or through which the second partials of the constraint relationship are returned with respect to time and the principal axes variables. The set of derivatives UCOSUB returns depends on the value of idrsel(2). In this table, q represents the variables, t stands for time, and F refers to the constraint equation.
If idresel (2) is: 0 array is : No evaluation
If idresel (2) is: 1 array is : array(m) =
If idresel (2) is: 2 array is : array(m) =
If any of the elements of array are symbolically zero, they don't need to be defined.
scalar
A double-precision variable for returning the residue (the error relative to zero) of the implicit constraint expression, the nonprincipal axes variable-dependent portion of the constraint expression (the value of the constraint expression if all principal axes variables are zero), or the various time derivatives of the constraint expression.
The value UCOSUB returns to Adams Solver depends on the value of idrsel(1). In the following table, q represents the variables, t stands for time, F refers to the constraint equation, and f refers to the equation when all variables (q) are set equal to zero.
If idresel (1) is: (scalar is: )
0 (No evaluation )
1 (scalar = F(q,t))
2 (scalar = )
3 (scalar =
4 (scalar = f(t))
xmatrx
A double-precision thirty-by-thirty array that returns to Adams Solver the second derivatives of the constraint expression with respect to the principal axes variables. The second derivatives UCOSUB returns the value of idrsel(3):
If idresel (3) is: (xmatrx is: )
0 (No evaluation )
1 (xmatrx(m,n) = )
The letter q represents the variables, t stands for time, and F refers to the constraint equation. If any of the elements of xmatrx are symbolically zero, they need not be defined.

Extended Definition

The standard constraint statements are usually adequate for defining commonly occurring displacement constraints between marker pairs. For displacement constraint combinations not available through these statements or for constraints involving velocity variables, you should use the FUNCTION=USER() argument in the UCON statement, and write a UCOSUB to define the constraint. The constraints defined in the subroutine can incorporate velocity variables. You can select as many as thirty displacements and/or velocities of part principal axes to be the variables in the constraint relationship for a UCON statement. Each UCON statement removes one degree of freedom from the system.
At every evaluation step, Adams Solver evaluates UCOSUB to determine the value of the constraints. During the initialization of UCOSUB, the utility subroutine UCOVAR should be called to declare the variables used in the relationship. PART statement identifiers and type codes identify the variables. To preserve the generality of UCOSUB, the identifiers and the type codes can be passed through the parameter list of the UCON statement.
For the formulation of constraints, you cannot access information with SYSARY or SYSFNC. You can, however, access information with AKISPL or CUBSPL (see AKISPL, CUBSPL, and UCOVAR). You must set up UCOSUB system dependencies using UCOVAR, and use system information from the q parameter only.
For each system constraint, Adams Solver formulates a governing constraint equation. For standard Adams Solver constraint statements, symbolic partial derivatives of the constraint equation with respect to the system variables have been pre-computed and stored in the program for use in the system Jacobian when the particular constraint is involved.
When you write a UCOSUB, equations of motion are added to the set of equations Adams Solver generates for the standard constraint statements. You must provide the first and second derivatives of the constraint relationship with respect to the set of variables. You must code the constraint relationship in the implicit form. For information on implicit forms, see DIFF statement (C++ or FORTRAN).
 
Caution:  
When selecting the displacements or the velocities of the part principal axes for the constraint, remember that the part principal axes are not always identical to those of the part center-of-mass marker (CM). The following list summarizes the circumstances in which the part principal axes may differ from those of the part center-of-mass marker.
When the PART statement does not include the CM argument, the principal axes default to the body coordinate system.
Whenever the center-of-mass marker z-axis is parallel to the z-axis of the ground reference frame at time zero, Adams Solver permutes the internal representation of the principal axes by 90-degree rotations to avoid an Euler matrix singularity.
If the IP argument in the PART statement includes products of inertia, Adams Solver computes the inertial representation of the principal axes so that the products of inertia become zero.
When specifying an IM marker, Adams Solver computes the principal axes, which may or may not be the axes of the CM marker.
When the iflag argument is not zero, Adams sets q to zero. When you execute Adams Solver, computations that divide by these values result in fatal errors. Before dividing by q values, you should check for nonzero values or ensure the iflag argument is zero.

Structure

A sample structure for UCOSUB is shown next. The comments explain how the subroutine works.
      SUBROUTINE UCOSUB (ID, TIME, Q, PAR, NPAR,     
&                   IDRSEL, IFLAG, SCALAR, ARRAY,      
&                   XMATRX)
C
C === Type and dimension statements ===================
C
C - External variable definitions ---------
C
      INTEGER                     ID
      DOUBLE PRECISION            TIME
      DOUBLE PRECISION            Q( 30 )
      DOUBLE PRECISION            PAR( * )
      INTEGER                     NPAR
      INTEGER                     IDRSEL( 3 )
      INTEGER                     IFLAG
      DOUBLE PRECISION            SCALAR
      DOUBLE PRECISION            ARRAY( 30 )
      DOUBLE PRECISION            XMATRX( 30, 30 )

C ID       Identifier of calling UCON statement
C TIME     Current time
C Q        Array of part state variables
C PAR      Array of passed statement parameters
C NPAR     Number of passed parameters
C IDRSEL   UCON values selection control flag
C IFLAG    Initialization pass flag
C SCALAR   Scalar value returned to ADAMS
C ARRAY    Partial derivatives
C XMATRX   Second partial derivatives
C
C - Local variable definitions -----------
C
      ...
C
C === Executable code =================================
C
C - Assign parameters to readable variable names --
C
         ...
C
C - Subroutine initialization -----------
C
      IF( IFLAG ) THEN
C
C Declare principal axis variables 
C
         CALL UCOVAR ( ... )
C
      ENDIF
C
C - Find implicit constraint relation -------
C
      IF ( IDRSEL(1) .EQ. 1 ) THEN
C
C Your algorithm
C
         ...
C
C Assign scalar
C
         SCALAR = ...
C
C - First time derivative of constraint relation --
C
      ELSE IF ( IDRSEL(1) .EQ. 2 ) THEN
C
C Your algorithm
C
         ...
C
C Assign first time derivative to scalar
C
         SCALAR = ...
C
C - Second time derivative of constraint ------
C
     relation
C
      ELSE IF ( IDRSEL(1) .EQ. 3 ) THEN
C
C Your algorithm
C
         ...
C
C Assign second time derivative to scalar
C
         SCALAR = ...
C
C - Nonprincipal-axes-dependent portion of ----
C
     constraint relation
C
      ELSE IF ( IDRSEL(1) .EQ. 4 ) THEN
C
C Your algorithm
C
         ...
C
C Assign nonprincipal-axes-dependent portion to scalar
C
         SCALAR = ...
C
      ENDIF
C
C - Evaluate array -----------------
C
C - First derivative of constraint relationship with
C     respect to the variables
C
      IF ( IDRSEL(2) .EQ. 1 ) THEN
C
C Your algorithm
C
         ...
C
C Assign array values
C
         ARRAY(1)  = ...
         ...
         ARRAY(30) = ...
C
C - Derivatives of prior first derivatives with --C     respect to time
C
      ELSE IF ( IDRSEL(2) .EQ. 2 ) THEN
C
C Your algorithm
C
         ...
C
C Assign array values
C
         ARRAY(1)  = ...
         ...
         ARRAY(30) = ...
C
      ENDIF
C
C - Derivatives of prior first derivatives with --
C     respect to the variables
C      IF ( IDRSEL(3) .EQ. 1 ) THEN
C
C Your algorithm
C
         ...
C
C Assign matrix values
C
         XMATRX(1, 1)   = ...
         ...
         XMATRX(30, 30) = ...
C
      ENDIF
C
      RETURN
      END

Examples

For an example of this subroutine, see ucosub.f.