386 lines
16 KiB
Markdown
386 lines
16 KiB
Markdown
<!-- source-page: 411 -->
|
||
|
||
stateOld(nblock,nstatev)
|
||
|
||
State variables at each material point at the beginning of the increment.
|
||
|
||
tempNew(nblock)
|
||
|
||
Temperatures at each material point at the end of the increment.
|
||
|
||
fieldNew(nblock,nfieldv)
|
||
|
||
Values of the user-defined field variables at each material point at the end of the increment.
|
||
|
||
enerIntern(nblock)
|
||
|
||
Internal energy per unit mass at each material point at the beginning of the increment.
|
||
|
||
# Example: Using more than one user-defined material model
|
||
|
||
To use more than one user-defined fabric material model, the variable cmname can be tested for different fabric material names inside user subroutine VFABRIC, as illustrated below:
|
||
|
||
```txt
|
||
if (cmname(1:4) .eq. 'MAT1') then
|
||
call VFABRIC_MAT1(argument_list)
|
||
else if (cmname(1:4) .eq. 'MAT2') then
|
||
call VFABRIC_MAT2(argument_list)
|
||
end if
|
||
```
|
||
|
||
VFABRIC\_MAT1 and VFABRIC\_MAT2 are the actual fabric material user subroutines containing the constitutive material models for each material MAT1 and MAT2, respectively. User subroutine VFABRIC merely acts as a directory here. The argument list can be the same as that used in subroutine VFABRIC. The material names must be in uppercase characters since cmname is passed in as an uppercase character string.
|
||
|
||
# Example: Influence of nonorthogonal material directions in highly anisotropic elastic material
|
||
|
||
As an example of the coding of user subroutine VFABRIC, consider a simple elastic lamina material with highly anisotropic properties. For a fabric the material definitions need not remain orthogonal with deformation, whereas the directions do remain orthogonal for a built-in elastic material. The simple VFABRIC routine given below defines an elastic fabric and can be used to compare the fabric and the built-in elastic materials under different loading conditions.
|
||
|
||
The user subroutine would be coded as follows:
|
||
|
||
```csv
|
||
subroutine vfabric(
|
||
C Read only (unmodifiable)variables -
|
||
1 nblock, ndim, npt, layer, kspt, kstep, kinc,
|
||
2 nstatev, nfieldv, nprops,
|
||
3 lOp, jElem, stepTime, totalTime, dt, cmname, coordMp,
|
||
4 charLength, props, density, braidAngle, fabricStrain,
|
||
5 fabricStrainInc,
|
||
```
|
||
|
||
<!-- source-page: 412 -->
|
||
|
||
```txt
|
||
6 tempOld, fieldOld, fabricStressOld, stateOld,
|
||
7 tempNew, fieldNew, enerIntern,
|
||
C Write only (modifiable) variables -
|
||
8 fabricStressNew, stateNew, enerInelas )
|
||
C
|
||
C NOTE: In addition to the above "Write only" variables,
|
||
C the thickness direction component of fabricStrainInc
|
||
C i.e, fabricStrainInc(*,ndirStrain) may also be set by the user
|
||
C for changing thickness as a function of material in-plane
|
||
C state.
|
||
C
|
||
include 'vaba_param.inc'
|
||
C
|
||
parameter( ndirStrain = 3, nshr = 1, ndirStress = 2,
|
||
one = 1.d0, two = 2.d0 )
|
||
C
|
||
C NOTE: The constants defined above are used for array
|
||
C dimensions and computation below.
|
||
C
|
||
dimension
|
||
* jElem(nblock),
|
||
* coordMp(nblock,ndim),
|
||
* charLength(nblock),
|
||
* props(nprops),
|
||
* density(nblock),
|
||
* braidAngle(nblock),
|
||
* fabricStrain(nblock,ndirStrain+nshr),
|
||
* fabricStrainInc(nblock,ndirStrain+nshr),
|
||
* tempOld(nblock),
|
||
* fieldOld(nblock,nfieldv),
|
||
* fabricStressOld(nblock,ndirStress+nshr),
|
||
* stateOld(nblock,nstatev),
|
||
* tempNew(nblock),
|
||
* fieldNew(nblock,nfieldv),
|
||
* fabricStressNew(nblock,ndirStress+nshr),
|
||
* stateNew(nblock,nstatev),
|
||
* enerIntern(nblock),
|
||
* enerInelas(nblock)
|
||
C
|
||
character*80 cmname
|
||
C
|
||
```
|
||
|
||
<!-- source-page: 413 -->
|
||
|
||
```python
|
||
C
|
||
C Read properties
|
||
E1 = props(1)
|
||
E2 = props(2)
|
||
xnu12 = props(3)
|
||
twiceG12 = two * props(4)
|
||
C
|
||
xnu21 = E2 * xnu12 / E1
|
||
C
|
||
C Let us assume:
|
||
xnu13 = xnu12
|
||
xnu23 = xnu21
|
||
C
|
||
xnu13OverE1 = xnu13/E1
|
||
xnu23OverE2 = xnu23/E2
|
||
C
|
||
fr = one / (one - xnu12 * xnu21)
|
||
D11 = E1 * fr
|
||
D22 = E2 * fr
|
||
D12 = E2 * xnu12 * fr
|
||
C
|
||
do k = 1, nblock
|
||
C
|
||
C Update the stress
|
||
stressInc11 = D11 * fabricStrainInc(k,1)
|
||
* + D12 * fabricStrainInc(k,2)
|
||
stressInc22 = D22 * fabricStrainInc(k,2)
|
||
* + D12 * fabricStrainInc(k,1)
|
||
stressInc12 = twiceG12 *
|
||
* fabricStrainInc(k,ndirStrain + 1)
|
||
C
|
||
fabricStressNew(k,1) = fabricStressOld(k,1)
|
||
* + stressInc11
|
||
fabricStressNew(k,2) = fabricStressOld(k,2)
|
||
* + stressInc22
|
||
C
|
||
C shear stress
|
||
fabricStressNew(k,ndirStress+1) =
|
||
* fabricStressOld(k,ndirStress+1) + stressInc12
|
||
C
|
||
C Thickness direction strain
|
||
```
|
||
|
||
<!-- source-page: 414 -->
|
||
|
||
```prolog
|
||
c
|
||
fabricStrainInc(k,ndirStrain) =
|
||
C * - ( xnu13OverE1 * stressInc11
|
||
C * + xnu23OverE2 * stressInc22
|
||
C *
|
||
C
|
||
end do
|
||
return
|
||
end
|
||
```
|
||
|
||
<!-- source-page: 415 -->
|
||
|
||
# 1.2.6 VFRIC: User subroutine to define frictional behavior for contact surfaces.
|
||
|
||
# Product: Abaqus/Explicit
|
||
|
||
# References
|
||
|
||
• “Frictional behavior,” Section 37.1.5 of the Abaqus Analysis User’s Guide
|
||
• \*FRICTION
|
||
• “VFRIC, VFRIC\_COEF, and VFRICTION,” Section 4.1.30 of the Abaqus Verification Guide
|
||
|
||
# Overview
|
||
|
||
User subroutine VFRIC:
|
||
|
||
• can be used to define the frictional behavior between contact pair surfaces;
|
||
• can be used when the classical Coulomb friction model is too restrictive and a more complex definition of shear transmission between contacting surfaces is required;
|
||
• must provide the entire definition of shear interaction between the contacting surfaces;
|
||
• can use and update solution-dependent state variables;
|
||
• cannot be used in conjunction with softened tangential surface behavior; and
|
||
• cannot be used with the general contact algorithm.
|
||
|
||
# Terminology
|
||
|
||
The use of user subroutine VFRIC requires familiarity with the following terminology.
|
||
|
||
# Surface node numbers
|
||
|
||
The “surface node number” refers to the position of a particular node in the list of nodes on the surface. For example, there are nSlvNod nodes on the slave surface. Number nSlvNod, is the surface node number of the nth node in this list; jSlvUid is the user-defined global number of this node. An Abaqus/Explicit model can be defined in terms of an assembly of part instances (see “Defining an assembly,” Section 2.10.1 of the Abaqus Analysis User’s Guide). In such models a node number in jSlvUid is an internally generated node number. If the original node number and part instance name are required, call the utility routine VGETPARTINFO (see “Obtaining part information,” Section 2.1.5).
|
||
|
||
# Contact points
|
||
|
||
The nodes on the slave surface that are in contact in the current time increment are defined as “contact points.” The number of contact points is passed into this subroutine as nContact. The array jConSlvid(nContact) gives the surface node numbers for the contact points.
|
||
|
||
<!-- source-page: 416 -->
|
||
|
||
A local coordinate system is defined for each contact point to facilitate specification of frictional forces and incremental slips. The local 1-direction for both two-dimensional and three-dimensional contact is tangential to the master surface, and it is defined by $\mathbf { t } _ { 1 } ~ = ~ d \mathbf { s } / | d \mathbf { s } |$ , where is the incremental slip vector. The incremental slip vector used to define $\mathbf { t } _ { 1 }$ corresponds to the incremental slip in the current time increment for penalty contact and the predicted incremental slip for kinematic contact. The master surface normal direction, $\mathbf { n } ,$ is the local 2-direction for two-dimensional contact and the local 3-direction for three-dimensional contact. The local 2-direction for three-dimensional contact is given by $\mathbf { t } _ { 2 } = \mathbf { n } \times \mathbf { t } _ { 1 }$ , which is also tangent to the master surface. The vectors are shown in Figure 1.2.6–1 and Figure 1.2.6–2. The direction cosines for $\mathbf { t } _ { 1 }$ and with respect to the global coordinate system are available in dirCosT1 and dirCosN, respectively. In the case of zero incremental slip $( d \mathbf { s } | = 0 )$ we choose an arbitrary direction for $\mathbf { t } _ { 1 }$ that is orthogonal to the normal direction, .
|
||
|
||

|
||
|
||
<details>
|
||
<summary>text_image</summary>
|
||
|
||
surface normal
|
||
slave node
|
||
master surface
|
||
n
|
||
ds
|
||
t₁
|
||
slip direction
|
||
incremental frictional slip
|
||
</details>
|
||
|
||
Figure 1.2.6–1 Local coordinate system for two-dimensional contact with VFRIC.
|
||
|
||
# Frictional forces
|
||
|
||
You specify the frictional force, fTangential, at each contact point in local coordinates in this subroutine. The array fTangential is dimensioned such that only the tangential components can be specified. Any components of the frictional force that are not specified will remain equal to zero. For three-dimensional contact with isotropic friction, only the first component of the frictional force need be specified since the second component should be zero. A “stick force” at each contact point is provided in the array fStickForce to assist you in setting the appropriate frictional force values. The stick force is the force required to prevent additional “plastic” slipping. The stick force at each contact point is provided as a scalar value as it would act in the direction opposite to $\mathbf { t } _ { 1 }$ . The stick force is computed prior to calling user subroutine VFRIC by either the kinematic or the penalty contact algorithm. See “Contact constraint enforcement methods in Abaqus/Explicit,” Section 38.2.3 of the Abaqus Analysis User’s Guide, for descriptions of the kinematic and penalty contact algorithms and the user interface for choosing between them. The first component of the frictional force should be in the range between
|
||
|
||
<!-- source-page: 417 -->
|
||
|
||

|
||
|
||
<details>
|
||
<summary>text_image</summary>
|
||
|
||
surface normal
|
||
slave node
|
||
master surface
|
||
n
|
||
ts
|
||
ds
|
||
t1
|
||
slip directions
|
||
incremental frictional slip
|
||
</details>
|
||
|
||
Figure 1.2.6–2 Local coordinate system for three-dimensional contact with VFRIC.
|
||
|
||
zero and minus the stick force value. Typically, the stick force will be positive and the first component of the applied frictional force will be negative, opposing the incremental slip. Penalty contact includes an elastic slip regime due to finite penalty stiffness, so occasionally, during recovery of elastic slip, the stick force will be negative, indicating that it is appropriate for the first component of the frictional force to be positive (i.e., acting in the same direction as the incremental slip). A noisy or unstable solution is likely to result if the first component of fTangential is set outside of the range between zero and negative the value of the stick force.
|
||
|
||
After user subroutine VFRIC is called, frictional forces that oppose the forces specified at the contact points are distributed to the master nodes. For balanced master-slave contact we then compute weighted averages of the frictional forces for both master-slave orientations. These forces are directly applied if the penalty contact algorithm is being used. If the kinematic contact algorithm is being used, the frictional forces are converted to acceleration corrections by dividing by the nodal masses.
|
||
|
||
User subroutine interface
|
||
```txt
|
||
subroutine vfric(
|
||
C Write only -
|
||
1 fTangential,
|
||
C Read/Write -
|
||
2 statev,
|
||
C Read only -
|
||
3 kStep, kInc, nContact, nFacNod, nSlvNod, nMstNod,
|
||
4 nFricDir, nDir, nStateVar, nProps, nTemp, nPred, numDefTfv,
|
||
5 jSlvUid, jMstUid, jConSlvid, jConMstid, timStep, timGlb,
|
||
```
|
||
|
||
<!-- source-page: 418 -->
|
||
|
||
```txt
|
||
6 dTimCur, surfInt, surfSlv, surfMst, lContType,
|
||
7 dSlipFric, fStickForce, fTangPrev, fNormal, frictionWork,
|
||
8 shape, coordSlv, coordMst, dirCosSl, dircosN, props,
|
||
9 areaSlv, tempSlv, preDefSlv, tempMst, preDefMst)
|
||
C
|
||
include `vaba_param.inc'
|
||
C
|
||
character*80 surfInt, surfSlv, surfMst
|
||
C
|
||
dimension props(nProps), statev(nStateVar,nSlvNod),
|
||
1 dSlipFric(nDir,nContact),
|
||
2 fTangential(nFricDir,nContact),
|
||
3 fTangPrev(nDir,nContact),
|
||
4 fStickForce(nContact), areaSlv(nSlvNod),
|
||
5 fNormal(nContact), shape(nFacNod,nContact),
|
||
6 coordSlv(nDir,nSlvNod), coordMst(nDir,nMstNod),
|
||
7 dirCosSl(nDir,nContact), dircosN(nDir,nContact),
|
||
8 jSlvUid(nSlvNod), jMstUid(nMstNod),
|
||
9 jConSlvid(nContact), jConMstid(nFacNod,nContact)
|
||
1 tempSlv(nContact), preDefSlv(nContact,nPred),
|
||
2 tempMst(numDefTfv), preDefMst(numDefTfv,nPred)
|
||
|
||
user coding to define fTangential
|
||
and, optionally, statev
|
||
|
||
return
|
||
end
|
||
```
|
||
|
||
# Variable to be defined
|
||
|
||
# fTangential(nFricDir, nContact)
|
||
|
||
This array must be updated to the current values of the frictional force components for all contact points in the local tangent directions. See Figure 1.2.6–1 and Figure 1.2.6–2 for definition of the local coordinate system. This array will be zero (no friction force) until you reset it.
|
||
|
||
# Variable that can be updated
|
||
|
||
# statev(nstateVar, nSlvNod)
|
||
|
||
This array contains the user-defined solution-dependent state variables for all the nodes on the slave surface. You define the size of this array (see “Frictional behavior,” Section 37.1.5 of the Abaqus Analysis User’s Guide, for more information). This array will be passed in containing the values of these variables prior to the call to user subroutine VFRIC. If any of the solution-dependent state variables is being used in conjunction with the friction behavior, it must be updated in this subroutine.
|
||
|
||
<!-- source-page: 419 -->
|
||
|
||
The state variables are available even for slave nodes that are not in contact. This may be useful when, for example, the state variables need to be reset for slave nodes that are not in contact.
|
||
|
||
Variables passed in for information
|
||
kStep
|
||
Step number.
|
||
|
||
kInc
|
||
Increment number.
|
||
|
||
nContact
|
||
Number of contacting slave nodes.
|
||
|
||
nFacNod
|
||
Number of nodes on each master surface facet (nFacNod is 2 for two-dimensional surfaces, nFacNod is 4 for three-dimensional surfaces). If the master surface is an analytical rigid surface, this variable is passed in as 0.
|
||
|
||
nSlvNod
|
||
Number of slave nodes.
|
||
|
||
nMstNod
|
||
Number of master surface nodes, if the master surface is made up of facets. If the master surface is an analytical rigid surface, this variable is passed in as 0.
|
||
|
||
nFricDir
|
||
Number of tangent directions at the contact points (nFricDir = nDir - 1).
|
||
|
||
nDir
|
||
Number of coordinate directions at the contact points. (In a three-dimensional model nDir will be two if the surfaces in the contact pair are two-dimensional analytical rigid surfaces or are formed by two-dimensional elements.)
|
||
|
||
nStateVar
|
||
Number of user-defined state variables.
|
||
|
||
nProps
|
||
User-specified number of property values associated with this friction model.
|
||
|
||
nTemp
|
||
1 if the temperature is defined and 0 if the temperature is not defined.
|
||
|
||
nPred
|
||
Number of predefined field variables.
|
||
|
||
<!-- source-page: 420 -->
|
||
|
||
# numDefTfv
|
||
|
||
Equal to nContact if the master surface is made up of facets. If the master surface is an analytical rigid surface, this variable is passed in as 1.
|
||
|
||
# jSlvUid(nSlvNod)
|
||
|
||
This array lists the user-defined global node numbers (or internal node numbers for models defined in terms of an assembly of part instances) of the nodes on the slave surface.
|
||
|
||
# jMstUid(nMstNod)
|
||
|
||
This array lists the user-defined global node numbers (or internal node numbers for models defined in terms of an assembly of part instances) of the nodes on the master surface. If the master surface is an analytical rigid surface, this array is passed in as a dummy array.
|
||
|
||
# jConSlvid(nContact)
|
||
|
||
This array lists the surface node numbers of the slave surface nodes that are in contact.
|
||
|
||
# jConMstid(nFacNod, nContact)
|
||
|
||
This array lists the surface node numbers of the master surface nodes that make up the facet with which each contact point is in contact. If the master surface is an analytical rigid surface, this array is passed in as a dummy array.
|
||
|
||
# timStep
|
||
|
||
Value of step time.
|
||
|
||
# timGlb
|
||
|
||
Value of total time.
|
||
|
||
# dtimCur
|
||
|
||
Current increment in time from $t = t _ { c u r r } - \Delta t$ to .
|
||
|
||
# surfInt
|
||
|
||
User-specified surface interaction name, left justified.
|
||
|
||
# surfSlv
|
||
|
||
Slave surface name.
|
||
|
||
# surfMst
|
||
|
||
Master surface name.
|
||
|
||
# lContType
|
||
|
||
Contact type flag. This flag is set based on the type of constraint enforcement method (see “Contact constraint enforcement methods in Abaqus/Explicit,” Section 38.2.3 of the Abaqus Analysis User’s Guide) being used: 1 for kinematic contact and 2 for penalty contact. Stick conditions are satisfied exactly with the kinematic contact algorithm; they are satisfied only approximately (subject to an automatically chosen penalty stiffness value) with the penalty contact algorithm.
|