Polygonal Contact Model Release 13-08-27
=======================


1 Introduction
--------------

The Polygonal Contact Model (PCM) is a contact algorithm for multibody dynamics. It uses polygonal body surfaces and implements the elastic foundation contact model.


2 Contents
----------

- ./src/ includes the C source code of PCM.

- ./simpack/interface/ includes Fortran code for using PCM as a SIMPACK user routine.

- ./simpack/models/ includes PCM demonstration models for SIMPACK.


3 MBS-Interface
---------------

PCM is designed to be used as force element in MBS-codes. There are three interface routines to be called:

- pcm_defcont.c defines a contact during pre-processing.

- pcm_calcont.c analyses a contact for a given system state.

- pcm_freemem.c deallocates PCM's memory.

All interface variables are implemented as pointers and do not return a function value (void) so that they can be called from Fortran as well as from C/C++ (check/remove pcm_platform.h for platformspecific Fortran substitutions).

Description of the interface variables:

void pcm_defcont( int    *task   /* i: Task Flag                                */
                , char   *name   /* i: Name of Contact                          */
                , int    *loade  /* i: Loading Mode of Contact Surface E        */
                , int    *loadf  /* i: Loading Mode of Contact Surface F        */
                , int    *winde  /* i: Winding Mode of Contact Surface E        */
                , int    *windf  /* i: Winding Mode of Contact Surface F        */
                , double *sfe    /* i: Scaling Factor for Contact Surface E     */
                , double *sff    /* i: Scaling Factor for Contact Surface F     */
                , char   *fncse  /* i: Path&Name of Contact Surface File E      */
                , char   *fncsf  /* i: Path&Name of Contact Surface File F      */
                , double *lpare  /* i: Loading Parameters for Contact Surface E */
                , double *lparf  /* i: Loading Parameters for Contact Surface F */
                , double *penmx  /* i: Max. Penetration                         */
                , double *ymode  /* i: Young's Module of Body E                 */
                , double *ymodf  /* i: Young's Module of Body F                 */
                , double *prate  /* i: Poisson's Ratio of Body E                */
                , double *pratf  /* i: Poisson's Ratio of Body F                */
                , double *ldepe  /* i: Layer Depth of Body E                    */
                , double *ldepf  /* i: Layer Depth of Body F                    */
                , int    *admod  /* i: Mode of Expansion Damping                */
                , double *adcmp  /* i: Compression Areal Damping Factor         */
                , double *adexp  /* i: Expansion Areal Damping Factor           */
                , int    *dtmod  /* i: Mode of Damping Transition               */
                , double *dtdpt  /* i: Depth of Damping Transition              */
                , double *frcoe  /* i: Friction Coefficient                     */
                , double *frvel  /* i: Friction Regularisation Velocity         */
                , int    *idcnt  /* o: ID of Contact                            */
                , int    *err    /* o: Error Flag: 0/1 = okay/Error             */
                , long   nname   /* i: Dimension of name                        */
                , long   nfncse  /* i: Dimension of fncse                       */
                , long   nfncsf  /* i: Dimension of fncsf                       */
                )

- task defines the operation mode of PCM:
  0 = collision detection only
  1 = layer contact: 2-pass master/slave
  2 = layer contact: master/slave = contact surface E/F
  3 = layer contact: master/slave = contact surface F/E

- name defines the name of the contact (used in messages)

- loade defines the loading mode for contact surface E
  0 = read wavefront-file (*.obj) defined by fncse
  1 = load surface data by callback function (to be implemented by user)

- loadf defines the loading mode for contact surface F
  0 = read wavefront-file (*.obj) defined by fncsf
  1 = load surface data by callback function (to be implemented by user)

- winde = 1 flips the faces (orientation) of contact surface E

- windf = 1 flips the faces (orientation) of contact surface F

- sfe is a factor applied to the coordinates (v_pcm := sfe * v_file) of contact surface E

- sff is a factor applied to the coordinates (v_pcm := sff * v_file) of contact surface F

- fncse defines path and name of the wavefront-file (*.obj) representing contact surface E (unused if loade==1)

- fncsf defines path and name of the wavefront-file (*.obj) representing contact surface F (unused if loadf==1)

- lpare defines callback loading parameters for contact surface E (to be defined by user; unused if loade==0)

- lparf defines callback loading parameters for contact surface F (to be defined by user; unused if loadf==0)

- penmx defines the max. penetration to be considered (unused if penmx==0.0)

- ymode [N/m^2] defines the Young's modulus of the elasic foundation of body E (ymode=0 -> rigid)

- ymodf [N/m^2] defines the Young's modulus of the elasic foundation of body F (ymodf=0 -> rigid)

- prate [-] defines the Poison's ratio of the elasic foundation of body E (0<prate<0.45)

- pratf [-] defines the Poison's ratio of the elasic foundation of body F (0<pratf<0.45)

- ldepe [m] defines the depth of the elasic foundation of body E (ldepe=0 -> rigid)

- ldepf [m] defines the depth of the elasic foundation of body F (ldepf=0 -> rigid)

- admod [-] defines the mode of the expansion damping:
  0 = no tensile contact force
  1 = no expansion damping
  2 = full expansion damping

- adcmp[Ns/m^3] defines the areal damping factor (F_d := adamp * v_n * A) of the elastic foundation during compression (approaching bodies)

- adexp[Ns/m^3] defines the areal damping factor (F_d := adamp * v_n * A) of the elastic foundation during expansion (departing bodies)

- dtmod defines the operation mode of the damping transition:
  = 0: none
  = 1: linear transition of depth dtdpt

- dtdpt [m] defines the depth of the damping transition

- frcoe [-] defines the sliding friction coefficient (F_t := frcoe * F_n) of the contact

- frvel [m/s] defines the upper limit of the static friction regularisation (v_t < frvel -> F_t := v_t/frvel * frcoe * F_n)

- idcnt is the ID of the contact defined by PCM

- err = 1 if an error occured during excecution of pcm_defcont

- nfncse is the dimension of fncse (obsolete for PCM, but required for Windoze Fortran compiler)

- nfncsf is the dimension of fncsf (obsolete for PCM, but required for Windoze Fortran compiler)

void pcm_calcont( int     *idcnt      /* i: ID of Contact                                */
                , double  A_EF[3][3]  /* i: Transformation Matrix RefSys(F)->RefSys(E)   */
                , double  r_EF[3]     /* i: Position Vector RefSys(E)->RefSys(F)         */
                , double  w_EF[3]     /* i: Angular Velocity Vector RefSys(E)->RefSys(F) */
                , double  v_EF[3]     /* i: Velocity Vector RefSys(E)->RefSys(F)         */
                , double  force[3]    /* o: Contact Force Vector acting on RefSys(E)     */
                , double  torque[3]   /* o: Contact Torque Vector acting on RefSys(F)    */
                , double  outval[25]  /* o: Additional Output Values                     */
                , int     *err        /* o: Error Code: 0 = No Error                     */
                )

- idcnt is the ID of the contact defined by PCM

- A_EF is the transformation matrix connecting marker M_F -> connecting marker M_E

- r_EF is the position vector connecting marker M_E -> connecting marker M_F w.r.t. M_E

- w_EF is the angular velocity vector connecting marker M_E -> connecting marker M_F w.r.t. M_E

- v_EF is the velocity vector connecting marker M_E -> connecting marker M_F w.r.t. M_E

- force is the contact force vector to be applied on body E at the origin of connecting marker M_F w.r.t. M_E

- torque is the contact torque vector to be applied on body E w.r.t. M_E

- outval contains 25 additional output values of the contact analysis:
  outval[ 0] = Number of BV Collision Tests
  outval[ 1] = Number of Triangle Intersection Tests
  outval[ 2] = Number of Intersection Lines
  outval[ 3] = Number of Intersection Polygons
  outval[ 4] = Number of Intersections
  outval[ 5] = Number of Contact Elements
  outval[ 6] = Contact Patch Area [m^2]
  outval[ 7] = Weighted Penetration [m]
  outval[ 8] = Maximum Penetration [m]
  outval[ 9] = Minimum normal Velocity [m/s]
  outval[10] = Weighted normal Velocity [m/s]
  outval[11] = Maximum normal Velocity [m/s]
  outval[12] = Minimum tangential Velocity [m/s]
  outval[13] = Weighted tangential Velocity [m/s]
  outval[14] = Maximum tangential Velocity [m/s]
  outval[15] = Weighted Contact Pressure [N/m^2]
  outval[16] = Maximum Contact Pressure [N/m^2]
  outval[17] = Weighted Contact Traction [N/m^2]
  outval[18] = Maximum Contact Traction [N/m^2]
  outval[19] = x of Weighted Contact Position Vector [m]
  outval[20] = y of Weighted Contact Position Vector [m]
  outval[21] = z of Weighted Contact Position Vector [m]
  outval[22] = x of Weighted Contact Normal Vector [m]
  outval[23] = y of Weighted Contact Normal Vector [m]
  outval[24] = z of Weighted Contact Normal Vector [m]

- err is an error code of the contact evaluation:
  =  0: No error occured during excecution of pcm_calcont
  =  1: Error in collision detection
  =  2: Error in creating intersection polygons
  =  3: Error in creating active elements
  =  4: Error in creating contact elements
  =  5: Error in calculating force&torque
  = 11: Cannot access root pointers
  = 12: Contact idcnt is not defined
  = 13: Cannot find contact idcnt

void pcm_freemem( int  *err )   /* o: Error Flag: 0/1 = okay/Error */

- err = 1 if an error occured during excecution of pcm_freemem


5 Hints
-------

- How to install PCM on SIMPACK 9.x?

  0 SIMPACK has to be installed with User Routines and appropriate Fortran and C compilers.
  1 cp ./src/* $SIMPACK_USER/src/ext/
  2 cp ./simpack/interface/uforce*.f $SIMPACK_USER/src/mbselem/
  3 Uncomment "#define SIMPACK 1" in $SIMPACK_USER/src/ext/pcm_env.h
  4 Build user library via User Routines GUI

- How to install PCM on SIMPACK 8.x?

  0 SIMPACK has to be installed with User Routines and appropriate Fortran and C compilers.
  1 cp ./src/* $SIMPACK_USER/src/ext/c/
  2 cp ./simpack/interface/uforce*.f $SIMPACK_USER/src/bibl/uforce/
  3 cp ./simpack/interface/include/spck_version_info.h $SIMPACK_USER/src/include/
  4 Uncomment "#define SIMPACK 1" in $SIMPACK_USER/src/ext/pcm_env.h
  5 Compile all copied routines via User Routines GUI
  6 Build shared libraries via User Routines GUI

- What is the meaning of the connecting markers?

  PCM uses the connecting markers M_E and M_F as reference frames of the contact surfaces and as usual force element markers used for determination of the relative kinematics and application of the resulting force and torque vectors. Note that all vectors have to be represented and derivated in marker frame M_E (SIMPACK: "from"/M_i, ADAMS: M_j) and the resulting torque presumes that the force vector acts (on both bodies) at the origin of marker frame M_F.

- What operation mode should I use?

  In the master/slave modes the triangles of the master surface are used as contact elements which define the local contact forces and their directions. Therefore as a rule the surface of finer discretisation / higher complexity should be used as master.
  The 2-pass mode results in a better approximation if the polygon sizes of the surfaces are rather similar.

- What is the max. penetration?

  In rare undercut situations it may happen that contact elements with wrong penetrations become active. The max. penetration is a workaround to disable these elements. Usually it is not required.

- How to implement alternate loading of contact surfaces?

  Add the code in ./src/pcm_addcosu.c. Search for "ADD CODE". Use loading parameters lpare/lparf to pass necessary data to your code.


6 To Do List
------------


7 References
------------

See www.pcm.hippmann.org


8 Contact
---------

pcm@hippmann.org


9 License
---------

PCM is public domain software.


10 No Warranty
--------------

BECAUSE PCM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.


11 Release Notes
----------------

- 130827:
  * Corrected handling of degenerated intersection lines (pcm_creaispo, pcm_cractelm)
  * Improved and simplified contact element generation (pcm_crcemasl, pcm_calcntel)
  * Improved performance of pre- and post-processing (pcm_centsort, pcm_freemem)
  * Introduced max. penetration

- 121023:
  * Fixed memory leaks (pcm_freemem.c)
  * Single function call messages
  * Enabled SIMPACK 9.x

- 090625:
  * Removed static variables to enable multi threaded evaluation

- 090618:
  * Improved messages, introduced contact and contact surface names
  * Introduced configurable print function (pcm_print) instead of printf

- 090326:
  * Check for perpendicular triangle normals in penetration determination (pcm_calcntel)
  * Enabled removing of too short last intersection line (pcm_creaispo)

- 090318:
  * Free contact state memory also in case of error during contact calculation
  * Added error codes of contact calculation (pcm_calcont)

- 080117:
  * Use root pointers for global data (pcm_root) and minor bugfixes to enable build on IRIX
  * Removed testprints

- 080107:
  * Excluded platformspecific substitutions pcm.h -> pcm_platform.h
  * Minor bugfixes to avoid compiler warnings

- 080103:
  * Interface of pcm_defcont and SIMPACK user routine code have been modified!
  * Added optional loading of contact surfaces by callback function

- 080102:
  * Interface of pcm_defcont and SIMPACK user routine code and models have been modified!
  * Added expansion damping mode
  * Added (currently unused) contact element output values (master surface and facet id, normal force)
  * Removed CPU-time output values (pcm_calcont)
  * Simplified uforce21, removed pcm_matf2c

- 071117:
  * Merged all includes into pcm.h
  * Removed contact element generation by variational interpolation method

- 071115:
  * Fixed bug in calculation of weighted contact vectors (pcm_calctfrc)

- 070803:
  * Changed platformspecific function names to lower case on Windoze (for SIMPACK >= 8.804)
  * Added initialisation of ftot (pcm_calctfrc)

- 040930:
  * Minor modifications for proper compile and test on Linux

- 040327:
  * Call fflush to avoid buffering of pre-processing prints on Windoze (pcm_defcont)
  * Fixed bug in initialisation of icosu (pcm_creabvtr)
  * Added call tree documentation file calltree.txt

- 031229:
  * Introduced numerical limit for enhanced robustness in calculating contact elements (pcm_calcntel)

- 030827:
  * First official release
