FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
fstr_contact_elem_slag.f90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! Copyright (c) 2019 FrontISTR Commons
3 ! This software is released under the MIT License, see LICENSE.txt
4 !-------------------------------------------------------------------------------
7  use hecmw
8  use elementinfo
9  use mcontactdef
10  use msurfelement
13  implicit none
14 
15  public :: getcontactstiffness_slag
17  public :: gettiedstiffness_slag
18  public :: gettiednodalforce_slag
19 
20 contains
21 
22  subroutine getcontactstiffness_slag(ctState,tSurf,iter,tPenalty,fcoeff,lagrange,stiffness)
23 
24  use msurfelement
25  type(tcontactstate) :: ctstate
26  type(tsurfelement) :: tsurf
27  integer(kind=kint) :: iter
28  integer(kind=kint) :: nnode
29  integer(kind=kint) :: i, j
30  real(kind=kreal) :: normal(3)
31  real(kind=kreal) :: ntm((l_max_surface_node + 1)*3)
32  real(kind=kreal) :: fcoeff, tpenalty
33  real(kind=kreal) :: lagrange
34  real(kind=kreal) :: tf_trial(3), length_tft
35  real(kind=kreal) :: tangent(3)
36  real(kind=kreal) :: stiffness(:,:)
37  real(kind=kreal) :: tm(3, 3*(l_max_surface_node+1)), tt(3, 3*(l_max_surface_node+1))
38  real(kind=kreal) :: q((l_max_surface_node+1)*3)
39  real(kind=kreal) :: dot_tn
40 
41  nnode = size(tsurf%nodes)
42 
43  stiffness = 0.0d0
44 
45  ! Compute Tm and Tt matrices using standard shape functions
46  call computetm_tt(ctstate, tsurf, fcoeff, tm, tt)
47 
48  normal(1:3) = ctstate%direction(1:3)
49 
50  ! Compute nTm = Tm^T * n for KKT constraint (Lagrange multiplier row/column)
51  ntm(1:(nnode+1)*3) = matmul(transpose(tm(1:3, 1:3*(nnode+1))), normal)
52 
53  i = (nnode+1)*3 + 1
54  do j = 1, (nnode+1)*3
55  stiffness(i,j) = ntm(j); stiffness(j,i) = ntm(j)
56  enddo
57 
58  if( fcoeff /= 0.0d0 ) then
59  if( lagrange>0.0d0 .or. iter==1 ) then
60 
61  ! Stick friction: K_uu^stick = ρ * Tt^T * Tt
62  do i = 1, (nnode+1)*3
63  do j = 1, i
64  stiffness(i,j) = stiffness(i,j) + tpenalty * dot_product(tt(1:3,i), tt(1:3,j))
65  ! Fill symmetric part
66  if (i /= j) then
67  stiffness(j,i) = stiffness(i,j)
68  endif
69  enddo
70  enddo
71 
72  if( ctstate%state == contactslip ) then
73 
74  tf_trial(1:3) = ctstate%tangentForce_trial(1:3)
75  length_tft = dsqrt(dot_product(tf_trial,tf_trial))
76  tangent(1:3) = tf_trial(1:3)/length_tft
77 
78  ! Compute q = Tm^T * tangent
79  q(1:(nnode+1)*3) = matmul(transpose(tm(1:3, 1:3*(nnode+1))), tangent)
80 
81  ! Slip correction:
82  dot_tn = dot_product(tangent, normal)
83 
84  do i = 1, (nnode+1)*3
85  do j = 1, i
86  stiffness(i,j) = stiffness(i,j) + tpenalty * (-q(i)*q(j) + q(i)*ntm(j)*dot_tn)
87  if (i /= j) then
88  stiffness(j,i) = stiffness(i,j)
89  endif
90  enddo
91  enddo
92 
93  ! Scale (u,u) block by (μλ/|t_tr|)
94  stiffness(1:(nnode+1)*3,1:(nnode+1)*3) = (fcoeff*lagrange/length_tft) * stiffness(1:(nnode+1)*3,1:(nnode+1)*3)
95 
96  ! (u,λ) cross term:)
97  stiffness(1:(nnode+1)*3, (nnode+1)*3+1) = stiffness(1:(nnode+1)*3, (nnode+1)*3+1) + fcoeff * q(1:(nnode+1)*3)
98 
99  endif
100  endif
101  endif
102 
103  end subroutine getcontactstiffness_slag
104 
105  subroutine getcontactnodalforce_slag(ctState,tSurf,ndCoord,ndDu,tPenalty,fcoeff,lagrange,ctNForce,ctTForce,cflag)
106 
107  use msurfelement
108  type(tcontactstate) :: ctstate
109  type(tsurfelement) :: tsurf
110  integer(kind=kint) :: nnode
111  integer(kind=kint) :: j
112  real(kind=kreal) :: fcoeff, tpenalty
113  real(kind=kreal) :: lagrange
114  real(kind=kreal) :: ndcoord(:), nddu(:)
115  real(kind=kreal) :: normal(3)
116  real(kind=kreal) :: ntm((l_max_surface_node + 1)*3)
117  real(kind=kreal) :: tf_trial(3), length_tft, tangent(3), tf_final(3)
118  real(kind=kreal) :: ctnforce(:)
119  real(kind=kreal) :: cttforce(:)
120  logical :: cflag
121 
122  real(kind=kreal) :: tm(3, 3*(l_max_surface_node+1)), tt(3, 3*(l_max_surface_node+1))
123 
124  ctstate%multiplier(1) = lagrange
125 
126  nnode = size(tsurf%nodes)
127 
128  ctnforce = 0.0d0
129  cttforce = 0.0d0
130 
131  ! Compute Tm matrix (Tt not needed, pass fcoeff=0 to skip)
132  call computetm_tt(ctstate, tsurf, fcoeff, tm, tt)
133 
134  normal(1:3) = ctstate%direction(1:3)
135 
136  ! Compute nTm = Tm^T * normal
137  ntm(1:(nnode+1)*3) = -matmul(transpose(tm(1:3, 1:3*(nnode+1))), normal)
138 
139  do j = 1, (nnode+1)*3
140  ctnforce(j) = lagrange*ntm(j)
141  enddo
142  j = (nnode+1)*3 + 1
143  ctnforce(j) = dot_product(ntm(1:(nnode+1)*3),ndcoord(1:(nnode+1)*3))
144 
145  if(fcoeff /= 0.0d0 .and. lagrange > 0.0d0)then
146 
147  if( cflag ) then !calc tf_final and set it to tangentForce_final
148  ctstate%reldisp(1:3) = matmul(tt(1:3,1:3*(nnode+1)), nddu(1:3*(nnode+1)))
149 
150  call gettrialfricforceandcheckfricstate(ctstate,fcoeff,tpenalty,lagrange)
151 
152  if( ctstate%state == contactstick ) then
153  tf_final(1:3) = ctstate%tangentForce_trial(1:3)
154  elseif( ctstate%state == contactslip ) then
155  tf_trial(1:3) = ctstate%tangentForce_trial(1:3)
156  length_tft = dsqrt(dot_product(tf_trial,tf_trial))
157  tangent(1:3) = tf_trial(1:3)/length_tft
158  tf_final(1:3) = fcoeff*dabs(lagrange)*tangent(1:3)
159  endif
160  ctstate%tangentForce_final(1:3) = tf_final(1:3)
161  else ! just set tangentForce_final to tf_final (used for fstr_ass_load_contact)
162  tf_final(1:3) = ctstate%tangentForce_final(1:3)
163  endif
164 
165  ! Distribute friction force using Tm: ctTForce = -Tm^T * tf_final
166  cttforce(1:(nnode+1)*3) = -matmul(transpose(tm(1:3, 1:3*(nnode+1))), tf_final)
167 
168  endif
169 
170  end subroutine getcontactnodalforce_slag
171 
172  subroutine gettiedstiffness_slag(ctState,tSurf,idof,stiffness)
173  use msurfelement
174  type(tcontactstate) :: ctstate
175  type(tsurfelement) :: tsurf
176  integer(kind=kint) :: nnode
177  integer(kind=kint) :: idof
178  real(kind=kreal) :: stiffness(:,:)
179 
180  integer(kind=kint) :: i, j
181  real(kind=kreal) :: ntm((l_max_surface_node+1)*3)
182  real(kind=kreal) :: tm(3, 3*(l_max_surface_node+1)), tt(3, 3*(l_max_surface_node+1))
183  real(kind=kreal) :: e_idof(3)
184 
185  nnode = size(tsurf%nodes)
186  stiffness = 0.0d0
187 
188  ! Compute Tm matrix
189  call computetm_tt(ctstate, tsurf, 0.0d0, tm, tt)
190 
191  ! Create unit vector in idof direction
192  e_idof = 0.0d0
193  e_idof(idof) = 1.0d0
194 
195  ! Compute nTm = Tm^T * e_idof
196  ! This gives constraint direction for tied contact
197  ntm(1:(nnode+1)*3) = matmul(transpose(tm(1:3, 1:3*(nnode+1))), e_idof)
198 
199  i = (nnode+1)*3 + 1
200  do j = 1, (nnode+1)*3
201  stiffness(i,j) = ntm(j); stiffness(j,i) = ntm(j)
202  enddo
203 
204  end subroutine gettiedstiffness_slag
205 
206  subroutine gettiednodalforce_slag(ctState,tSurf,idof,ndu,lagrange,ctNForce,ctTForce)
207  use msurfelement
208  type(tcontactstate) :: ctstate
209  type(tsurfelement) :: tsurf
210  integer(kind=kint) :: nnode
211  integer(kind=kint) :: idof
212  real(kind=kreal) :: ndu(:)
213  real(kind=kreal) :: lagrange
214  real(kind=kreal) :: ctnforce(:)
215  real(kind=kreal) :: cttforce(:)
216 
217  integer(kind=kint) :: j
218  real(kind=kreal) :: normal(3)
219  real(kind=kreal) :: ntm((l_max_surface_node + 1)*3)
220  real(kind=kreal) :: ttm((l_max_surface_node + 1)*3)
221  real(kind=kreal) :: tm(3, 3*(l_max_surface_node+1)), tt(3, 3*(l_max_surface_node+1))
222  real(kind=kreal) :: e_idof(3), e_normal(3), e_tangent(3)
223 
224  nnode = size(tsurf%nodes)
225 
226  ctnforce = 0.0d0
227  cttforce = 0.0d0
228 
229  ! Compute Tm matrix
230  call computetm_tt(ctstate, tsurf, 0.0d0, tm, tt)
231 
232  normal(1:3) = ctstate%direction(1:3)
233 
234  ! Create unit vector in idof direction
235  e_idof = 0.0d0
236  e_idof(idof) = 1.0d0
237 
238  ! Normal component: -normal(idof) * normal (OLD: nTm(1:3) = -normal(idof)*normal(1:3))
239  e_normal = -normal(idof) * normal
240 
241  ! Tangential component: -e_idof - e_normal (OLD: tTm(idof)=-1.0; tTm(1:3)-=nTm(1:3))
242  e_tangent = -e_idof - e_normal
243 
244  ! Compute nTm and tTm using Tm^T
245  ntm(1:(nnode+1)*3) = matmul(transpose(tm(1:3, 1:3*(nnode+1))), e_normal)
246  ttm(1:(nnode+1)*3) = matmul(transpose(tm(1:3, 1:3*(nnode+1))), e_tangent)
247 
248  do j = 1, (nnode+1)*3
249  ctnforce(j) = lagrange*ntm(j)
250  cttforce(j) = lagrange*ttm(j)
251  enddo
252  j = (nnode+1)*3 + 1
253  ctnforce(j) = dot_product(ntm(1:(nnode+1)*3),ndu(1:(nnode+1)*3))
254  cttforce(j) = dot_product(ttm(1:(nnode+1)*3),ndu(1:(nnode+1)*3))
255  end subroutine gettiednodalforce_slag
256 
257 end module m_fstr_contact_elem_slag
This module encapsulate the basic functions of all elements provide by this software.
Definition: element.f90:43
Definition: hecmw.f90:6
Common utilities for contact element calculations.
subroutine, public computetm_tt(ctState, tSurf, fcoeff, Tm, Tt)
Compute Tm (relative displacement mapping) and optionally Tt (tangential mapping) This subroutine con...
subroutine, public gettrialfricforceandcheckfricstate(ctstate, fcoeff, tPenalty, lagrange)
This subroutine calculates trial friction force and checks friction state.
Slag method implementations for contact element calculations.
subroutine, public gettiednodalforce_slag(ctState, tSurf, idof, ndu, lagrange, ctNForce, ctTForce)
subroutine, public getcontactnodalforce_slag(ctState, tSurf, ndCoord, ndDu, tPenalty, fcoeff, lagrange, ctNForce, ctTForce, cflag)
subroutine, public gettiedstiffness_slag(ctState, tSurf, idof, stiffness)
subroutine, public getcontactstiffness_slag(ctState, tSurf, iter, tPenalty, fcoeff, lagrange, stiffness)
This module provides geometric calculations for contact.
This module manages the data structure for contact calculation.
integer, parameter contactslip
integer, parameter contactstick
This module manages surface elements in 3D It provides basic definition of surface elements (triangla...
Definition: surf_ele.f90:8
integer(kind=kint), parameter l_max_surface_node
Definition: surf_ele.f90:16
This structure records contact status.
Structure to define surface group.
Definition: surf_ele.f90:23