COUSUB, COUXX, COUXX2

The COUSUB, COUXX, and COUXX2 subroutines define a user-defined COUPLER (C++ or FORTRAN):
COUSUB specifies the coupler constraint as a function of the displacements of the joints being coupled.
COUXX returns to Adams Solver the first partial derivatives of the coupler constraint, with respect to each joint displacement.
COUXX2 returns the matrix of second partial derivatives of the coupler constraint, with respect to the joint displacements.
 
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; Cousub for example. Doing this ensures that Adams Solver correctly distinguishes a C style subroutine from Fortran and calls with the appropriate interface.

Use

Corresponding Command

Calling Sequence

SUBROUTINE COUSUB (id, time, par, npar, disp, ndisp, iflag, phi)
SUBROUTINE COUXX (id, time, par, npar, disp, ndisp, iflag, dfda)
SUBROUTINE COUXX2 (id, time, par, npar, disp, ndisp, iflag, dfda2)

Input Arguments

 
id
An integer variable that specifies the identifier of the COUPLER statement whose constraint function is being specified.
time
A double-precision variable that contains the current simulation time.
par
A double-precision array that contains the constants taken, in order, from the list of values provided with the USER argument in the COUPLER statement.
npar
An integer variable containing the number of entries in the PAR array.
disp
A double-precision array containing the instantaneous joint displacements. Translational displacements are in units of length and rotational displacements are in radians.
ndisp
An integer variable that defines the size of the DISP array. This is equal to the number of joints being coupled in the COUPLER statement.
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 1 or 3 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

 
phi
A double-precision scalar that contains the value of the coupler constraint equation.
The constraint equation must be specified in implicit form. For example, the equation must be in the form: f (disp) = 0.
dfda
A double-precision array of length ndisp that contains the partial derivatives of phi with respect to disp. Therefore,
dfda2
A double-precision array of dimensions ndisp that contains the second partials derivatives of phi with respect to disp.
Therefore,

Extended Definition

The COUPLER statement is used to relate the motion of two or more joints. If the relationship between the motion in a set consisting of two or three joints is linear, the scale factors relating the motion can be directly specified in the dataset.
However, when the relationship between the joints is nonlinear in nature, the equation specifying this relationship must be specified in the user-written subroutines COUSUB, COUXX, and COUXX2. Therefore, if d1, d2, and d3 are displacement/rotations in three translational or revolute joints, the relationship between them may be written analytically as: ƒ1 (d1) + ƒ2(d2) + ƒ3(d3) = 0
COUSUB, COUXX, and COUXX2 must only be functions of the input variables specified above. You cannot call SYSFNC or SYSARY to access other system states.

FORTRAN - Prototype

A sample structure for COUSUB, COUXX, and COUXX2 is shown next. The comments explain the logical structure of each of the subroutines.

COUSUB

SUBROUTINE COUSUB (ID, TIME, PAR, NPAR, DISP,    &                   NDISP, IFLAG, PHI)
C
C+----------------------------------------------------*
C
C Inputs:
C      INTEGER          ID      DOUBLE PRECISION TIME      DOUBLE PRECISION PAR(*)      INTEGER          NPAR      DOUBLE PRECISION DISP(*)      INTEGER          NDISP      LOGICAL          IFLAGCC Outputs:
C      DOUBLE PRECISION PHICC Local Variables:
C      ...      ...
C
C+----------------------------------------------------*
C     Executable Code
C+----------------------------------------------------*
C
C      IF (IFLAG) THEN
C
C+----------------------------------------------------*
C        Initialization pass: Initialize necessaryC        local variables
C+----------------------------------------------------*C         ...         ...
C      ELSEC
C+----------------------------------------------------*
C        Evaluation pass: Define Phi the
C        coupler constraint
C+----------------------------------------------------*
C         ...         ...        
 PHI = ...
C    
  ENDIF
C
C      
RETURN     
 END
 

COUXX

     SUBROUTINE COUXX (ID, TIME, PAR, NPAR, DISP,
    &                  NDISP, IFLAG, DFDA)
C
C+----------------------------------------------------*
C
C Inputs:
C
     INTEGER          ID
     DOUBLE PRECISION TIME
     DOUBLE PRECISION PAR(*)
     INTEGER          NPAR
     DOUBLE PRECISION DISP(*)
     INTEGER          NDISP
     INTEGER          IFLAG
C
C Outputs:
C
     DOUBLE PRECISION DFDA(*)
C
C Local Variables:
C
     ...
     ...
C
C+----------------------------------------------------*
C
    Executable Code
C+----------------------------------------------------*
C
C
     IF (IFLAG) THEN
C
C+----------------------------------------------------*
C
       Initialization pass: Initialize
C
       necessary local variables
C+----------------------------------------------------*
C
        ...
        ...C
     ELSE
C
C+----------------------------------------------------*
C
       Evaluation pass: Define the partial
C
       derivatives of the coupler constraint
C+----------------------------------------------------*
C
        ...
        ...
        DFDA(1) = ...
        DFDA(2) = ...
        ...
C
     ENDIF
C
C
     RETURN
     END

COUXX2

      SUBROUTINE COUXX2 (ID, TIME, PAR, NPAR, DISP,
    &                  NDISP, IFLAG, DFDA2)
C
C+----------------------------------------------------*
C
C Inputs:
C
     INTEGER          ID
     DOUBLE PRECISION TIME
     DOUBLE PRECISION PAR(*)
     INTEGER          NPAR
     DOUBLE PRECISION DISP(*)
     INTEGER          NDISP
     LOGICAL          IFLAG
C
C Outputs:
C
     DOUBLE PRECISION DFDA2(NDISP)
C
C Local Variables:
C
     ...
     ...
C
C+----------------------------------------------------*
C
    Executable Code
C+----------------------------------------------------*
C
C
     IF (IFLAG) THEN
C
C+----------------------------------------------------*
C
       Initialization pass: Initialize
C
       necessary local variables
C+----------------------------------------------------*
C
        ...
        ...
C
     ELSE
C
C+----------------------------------------------------*
C
       Evaluation pass: Define the second partial
C
       derivatives of the coupler constraint
C+----------------------------------------------------*
C
        ...
        ...
        DFDA2(1) = ...
        DFDA2(2) = ...
        ...
        ...
C
     ENDIF
C
C
     RETURN
     END
 

C Style - Prototype

typedef void adams_c_COUSUB(const struct sAdamsCoupler* coupler, double TIME, double*, int IFLAG, double* PHI);
typedef void adams_c_COUXX(const struct sAdamsCoupler* coupler, double TIME, double*, int IFLAG, double* dFda);
typedef void adams_c_COUXX2(const struct sAdamsCoupler* coupler, double TIME, double*, int IFLAG, double* d2Fda2);
 
/*
* COUPLER -----------------------------------------------------------------
*/
struct sAdamsCoupler
{
int ID;
int NPAR;
const double* PAR;
int NJOINT;
int JOINTS[3];
char TYPE[3];
};
 
 

Examples

The mechanical system shown in Figure 1 consists of three rigid bodies and two joints; the first is a revolute joint and the second translational. The translational joint represents an actuator whose output displacement controls the angular motion in the revolute joint.
Let the displacement in the translational joint be defined as and the rotation in revolute joint as a.
Now assume that the variables s and a are related by the following equation:
s = 10 * Cos (a)
Figure 1. Simple Mechanical System Consisting of a Coupler
The dataset for this model is:
!Part/1, Ground
Marker/11
Marker/12
Part/2, Mass=10, Ip=10,10,10, Cm=21
Marker/21, Qp=0,-5,0, REU=90d,90d,0
Marker/22, REU=90d,0,0
Part/3, Mass=25, Ip=75,75,150, Cm=31
Marker/31, Qp=10,20,0, REU=90d,90d,0
Marker/32
Joint/1, Revolute, I=22, J=11
Joint/2, Translational, I=32, J=12
Motion/1, Joint=2, Function = 10*Time
Coupler/1, Joints=1,2, Function=User(10)
End

Subroutines COUSUB, COUXX, and COUXX2 for this model are:

COUSUB

      SUBROUTINE COUSUB (ID, TIME, PAR, NPAR, DISP,
   &                    NDISP, IFLAG, PHI)
C
C+----------------------------------------------------*
C
C Inputs:
C
     INTEGER          ID
     DOUBLE PRECISION TIME
     DOUBLE PRECISION PAR(*)
     INTEGER          NPAR
     DOUBLE PRECISION DISP(*)
     INTEGER          NDISP
     INTEGER          IFLAG
C
C Outputs:
C
     DOUBLE PRECISION PHI
C
C Local Variables:
C
     DOUBLE PRECISION LENGTH, S, ALPHA
C
C+----------------------------------------------------*
C
    Executable Code
C+----------------------------------------------------*
C
     IF (IFLAG) THEN
C
C
     there are no variables to initialize in this
C
     example
C
     ELSE
C
C+----------------------------------------------------*
C
     Evaluation pass: Define Phi the coupler
C
     constraint
C+----------------------------------------------------*
C
        LENGTH = PAR(1)
        ALPHA  = DISP(1)
        S      = DISP(2)
        PHI    = S - LENGTH * COS(ALPHA)
C
     ENDIF
C
     RETURN
     END

COUXX

      SUBROUTINE COUXX (ID, TIME, PAR, NPAR, DISP,
    &                   NDISP, IFLAG, DFDA)
C
C+----------------------------------------------------*
C
C Inputs:
C
     INTEGER          ID
     DOUBLE PRECISION TIME
     DOUBLE PRECISION PAR(*)
     INTEGER          NPAR
     DOUBLE PRECISION DISP(*)
     INTEGER          NDISP
     INTEGER          IFLAG
C
C Outputs:
C
     DOUBLE PRECISION DFDA(*)
C
C Local Variables:
C
     DOUBLE PRECISION LENGTH, S, ALPHA
C
C+----------------------------------------------------*
C
    Executable Code
C+----------------------------------------------------*C
     IF (IFLAG) THEN
C
C
     there are no variables to initialize in this example
C
     ELSE
C
C+----------------------------------------------------*
C
     Evaluation pass: Define the partial derivatives
C
     of the coupler constraint
C+----------------------------------------------------*
C
        LENGTH = PAR(1)
        ALPHA  = DISP(1)
        S      = DISP(2)
C
        DFDA(1) = + LENGTH * SIN(ALPHA)
        DFDA(2) = 1.0
C
     ENDIF
C
     RETURN
     END

COUXX2

     SUBROUTINE COUXX2 (ID, TIME, PAR, NPAR, DISP,
   &                    NDISP, IFLAG, DFDA2)
C
C+----------------------------------------------------*
C Inputs:
C
     INTEGER          ID
     DOUBLE PRECISION TIME
     DOUBLE PRECISION PAR(*)
     INTEGER          NPAR
     DOUBLE PRECISION DISP(*)
     INTEGER          NDISP
     INTEGER          IFLAG
C
C Outputs:
C
     DOUBLE PRECISION DFDA2(NDISP)
C
C Local Variables:
C
     DOUBLE PRECISION LENGTH, ALPHA, S
C
C+----------------------------------------------------*
C
    Executable Code
C+----------------------------------------------------*
C
     IF (IFLAG) THEN
C
C
      no variables to initialize in this example.
C
     ELSE
C
C+----------------------------------------------------*
C
     Evaluation pass: Define the second partial
C     derivatives of the coupler constraint
C+----------------------------------------------------*
C
        LENGTH = PAR(1)
        ALPHA  = DISP(1)
        S      = DISP(2)
        DFDA2(1) = LENGTH * COS(ALPHA)
        DFDA2(2) = 0.0
C
     ENDIF
C
     RETURN
     END