FrontISTR  6.0.0
Large-scale structural analysis program with finit element method
fstr_mat_con_contact.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 !-------------------------------------------------------------------------------
6 ! stiffness matrix structure for the contact analysis
7 ! employing standard Lagrange multiplier algorithm
8 
10 
11  use m_fstr
12  use elementinfo
17 
18  implicit none
19  private
21  public :: hecmwst_matrix_lagrange
23  public :: fstr_mat_con_contact
30 
31  integer(kind=kint), save :: NPL_org, NPU_org
32  type(nodeRelated), pointer, save :: list_nodeRelated_org(:) => null()
33 
34  type(nodeRelated), pointer :: list_nodeRelated(:) => null()
35 
36  logical :: permission = .false.
37 
38 contains
39 
40  integer(kind=kint) function fstr_get_num_lagrange_pernode(algtype)
41  integer(kind=kint) :: algtype
42  if( algtype == contactsslid .or. algtype == contactfslid ) then
44  else if( algtype == contacttied ) then
46  endif
47  end function
48 
51 
52  type(hecmwst_matrix) :: hecmat
53 
54  if( associated(list_noderelated_org) ) return
55  call hecmw_construct_noderelated_from_hecmat(hecmat, npl_org, npu_org, list_noderelated_org)
56 
58 
61  subroutine fstr_mat_con_contact(cstep,contact_algo,hecMAT,fstrSOLID,hecLagMAT,conMAT,is_contact_active_flag)
62 
63  integer(kind=kint) :: cstep
64  integer(kind=kint) :: contact_algo
65  type(hecmwst_matrix) :: hecmat
66  type(fstr_solid) :: fstrsolid
67  type(hecmwst_matrix_lagrange) :: heclagmat
68 
69  integer(kind=kint) :: num_lagrange
70  integer(kind=kint) :: countnon0lu_node, countnon0lu_lagrange
71  integer(kind=kint) :: numnon0_node, numnon0_lagrange
73  type (hecmwst_matrix) :: conmat
74  logical, intent(in) :: is_contact_active_flag
75 
76  integer(kind=kint) :: i, j, grpid
77  integer(kind=kint) :: count_n2s, count_s2s
78  integer(kind=kint) :: nlag
79 
80  count_n2s = 0
81  count_s2s = 0
82  do i = 1, fstrsolid%n_contacts
83  if( fstrsolid%contacts(i)%method == contactn2s ) count_n2s = count_n2s + 1
84  if( fstrsolid%contacts(i)%method == contacts2s ) count_s2s = count_s2s + 1
85  enddo
86  count_n2s = count_n2s + fstrsolid%n_embeds
87 
88  num_lagrange = 0
89  if( contact_algo == kcaslagrange ) then
90  do i = 1, fstrsolid%n_contacts
91  do j = 1, size(fstrsolid%contacts(i)%slave)
92  fstrsolid%contacts(i)%states(j)%id_lagrange = 0
93  enddo
94  enddo
95  do i = 1, fstrsolid%n_embeds
96  do j = 1, size(fstrsolid%embeds(i)%slave)
97  fstrsolid%embeds(i)%states(j)%id_lagrange = 0
98  enddo
99  enddo
100 
101  do i = 1, fstrsolid%n_contacts
102  grpid = fstrsolid%contacts(i)%group
103  if( .not. fstr_iscontactactive( fstrsolid, grpid, cstep ) ) cycle
104  nlag = fstr_get_num_lagrange_pernode(fstrsolid%contacts(i)%algtype)
105  do j = 1, size(fstrsolid%contacts(i)%slave)
106  if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
107  fstrsolid%contacts(i)%states(j)%id_lagrange = num_lagrange + 1
108  num_lagrange = num_lagrange + nlag
109  enddo
110  enddo
111 
112  do i = 1, fstrsolid%n_embeds
113  grpid = fstrsolid%embeds(i)%group
114  if( .not. fstr_iscontactactive( fstrsolid, grpid, cstep ) ) cycle
115  nlag = 3
116  do j = 1, size(fstrsolid%embeds(i)%slave)
117  if( .not. is_contact_active(fstrsolid%embeds(i)%states(j)%state) ) cycle
118  fstrsolid%embeds(i)%states(j)%id_lagrange = num_lagrange + 1
119  num_lagrange = num_lagrange + nlag
120  enddo
121  enddo
122  endif
123 
124  ! Get original list of related nodes
125  call hecmw_init_noderelated_from_org(hecmat%NP,num_lagrange,is_contact_active_flag,list_noderelated_org,list_noderelated)
126 
127  ! Construct new list of related nodes and Lagrange multipliers
128  countnon0lu_node = npl_org + npu_org
129  countnon0lu_lagrange = 0
130  if( is_contact_active_flag )then
131  if( count_n2s > 0 ) &
132  call getnewlistofrelatednodesandlagrangemultipliers(cstep,contact_algo, &
133  & hecmat%NP,fstrsolid,countnon0lu_node,countnon0lu_lagrange,list_noderelated)
134  if( count_s2s > 0 ) &
135  call getnewlistofrelatednodesandlagrangemultipliers_ss(cstep,contact_algo, &
136  & hecmat%NP,fstrsolid,countnon0lu_node,countnon0lu_lagrange,list_noderelated)
137  endif
138 
139  ! Construct new matrix structure(hecMAT&hecLagMAT)
140  numnon0_node = countnon0lu_node/2
141  numnon0_lagrange = countnon0lu_lagrange/2
142  call hecmw_construct_hecmat_from_noderelated(hecmat%N, hecmat%NP, hecmat%NDOF, &
143  & numnon0_node, num_lagrange, list_noderelated, hecmat)
144  call hecmw_construct_hecmat_from_noderelated(hecmat%N, hecmat%NP, hecmat%NDOF, &
145  & numnon0_node, num_lagrange, list_noderelated, conmat)
146  if( contact_algo == kcaslagrange ) call hecmw_construct_heclagmat_from_noderelated(hecmat%NP, &
147  & hecmat%NDOF, num_lagrange, numnon0_lagrange, is_contact_active_flag, list_noderelated, heclagmat)
148  call hecmw_finalize_noderelated(list_noderelated)
149 
150  ! Copy Lagrange multipliers
151  if( is_contact_active_flag .and. contact_algo == kcaslagrange ) &
152  call fstr_copy_lagrange_contact(fstrsolid,heclagmat)
153 
154  end subroutine fstr_mat_con_contact
155 
157  subroutine getnewlistofrelatednodesandlagrangemultipliers( &
158  & cstep, contact_algo, np, fstrSOLID, countNon0LU_node, countNon0LU_lagrange, list_nodeRelated )
159  integer(kind=kint),intent(in) :: cstep
160  integer(kind=kint),intent(in) :: contact_algo
161  integer(kind=kint),intent(in) :: np
162  type(fstr_solid),intent(in) :: fstrsolid
163  integer(kind=kint), intent(inout) :: countnon0lu_node, countnon0lu_lagrange
164  type(noderelated), pointer, intent(inout) :: list_noderelated(:)
165 
166  integer(kind=kint) :: grpid
167  integer(kind=kint) :: count_lagrange
168  integer(kind=kint) :: ctsurf, etype, nnode, ndlocal(l_max_surface_node + 1)
169  integer(kind=kint) :: i, j, k, nlag, algtype
170  real(kind=kreal) :: fcoeff
171  logical :: necessary_to_insert_node, necessary_to_insert_node_pair
172  logical :: is_contact_active_flag, is_damping_active_flag
173 
174  count_lagrange = 0
175  do i = 1, fstrsolid%n_contacts
176  ! Process only NODE-SURF pairs here (mortar pairs are handled by getNewListOF..._ss).
177  ! For a mortar pair states(j)%surface is -1, so master(ctsurf)%etype below would be an
178  ! out-of-bounds read on a mixed deck.
179  if( fstrsolid%contacts(i)%method /= contactn2s ) cycle
180 
181  grpid = fstrsolid%contacts(i)%group
182  if( .not. fstr_iscontactactive( fstrsolid, grpid, cstep ) ) cycle
183 
184  fcoeff = fstrsolid%contacts(i)%fcoeff
185  necessary_to_insert_node = ( fcoeff /= 0.0d0 .or. contact_algo == kcaalagrange )
186 
187  algtype = fstrsolid%contacts(i)%algtype
188  nlag = fstr_get_num_lagrange_pernode(algtype)
189  if( contact_algo == kcaalagrange ) nlag = 1
190  if( algtype == contacttied ) permission = .true.
191 
192  do j = 1, size(fstrsolid%contacts(i)%slave)
193  ! stick or sliding contact is active
194  is_contact_active_flag = is_contact_active(fstrsolid%contacts(i)%states(j)%state)
195  ! damping is active
196  is_damping_active_flag = fstrsolid%contacts(i)%states(j)%state == contactnear .and. &
197  & is_damping_enabled(fstrsolid%contacts(i))
198 
199  if( is_contact_active_flag .or. is_damping_active_flag ) then
200 
201  ctsurf = fstrsolid%contacts(i)%states(j)%surface
202  etype = fstrsolid%contacts(i)%master(ctsurf)%etype
203  if( etype/=fe_tri3n .and. etype/=fe_quad4n ) &
204  stop " ##Error: This element type is not supported in contact analysis !!! "
205  nnode = size(fstrsolid%contacts(i)%master(ctsurf)%nodes)
206  ndlocal(1) = fstrsolid%contacts(i)%slave(j)
207  ndlocal(2:nnode+1) = fstrsolid%contacts(i)%master(ctsurf)%nodes(1:nnode)
208 
209  ! For CONTACTNEAR damping (especially S-Lagrange + frictionless),
210  ! we still need slave-master connectivity to assemble damping terms.
211  necessary_to_insert_node_pair = necessary_to_insert_node .or. is_damping_active_flag
212 
213  if( is_contact_active_flag ) then
214  do k=1,nlag
215  if( contact_algo == kcaslagrange ) &
216  count_lagrange = fstrsolid%contacts(i)%states(j)%id_lagrange + k - 1
217  call hecmw_ass_noderelated_from_contact_pair(np, nnode, ndlocal, count_lagrange, permission, &
218  & necessary_to_insert_node_pair, list_noderelated_org, list_noderelated, countnon0lu_node, countnon0lu_lagrange )
219  enddo
220  else
221  ! NEAR damping only: no Lagrange multiplier, insert connectivity once
222  call hecmw_ass_noderelated_from_contact_pair(np, nnode, ndlocal, 0, permission, &
223  & necessary_to_insert_node_pair, list_noderelated_org, list_noderelated, countnon0lu_node, countnon0lu_lagrange )
224  endif
225 
226  end if
227 
228  enddo
229 
230  enddo
231 
232  do i = 1, fstrsolid%n_embeds
233 
234  grpid = fstrsolid%embeds(i)%group
235  if( .not. fstr_isembedactive( fstrsolid, grpid, cstep ) ) cycle
236 
237  necessary_to_insert_node = ( contact_algo == kcaalagrange )
238 
239  nlag = 3
240  if( contact_algo == kcaalagrange ) nlag = 1
241  permission = .true.
242 
243  do j = 1, size(fstrsolid%embeds(i)%slave)
244 
245  if( .not. is_contact_active(fstrsolid%embeds(i)%states(j)%state) ) cycle
246  ctsurf = fstrsolid%embeds(i)%states(j)%surface
247  etype = fstrsolid%embeds(i)%master(ctsurf)%etype
248  nnode = size(fstrsolid%embeds(i)%master(ctsurf)%nodes)
249  ndlocal(1) = fstrsolid%embeds(i)%slave(j)
250  ndlocal(2:nnode+1) = fstrsolid%embeds(i)%master(ctsurf)%nodes(1:nnode)
251 
252  do k=1,nlag
253  if( contact_algo == kcaslagrange ) &
254  count_lagrange = fstrsolid%embeds(i)%states(j)%id_lagrange + k - 1
255  call hecmw_ass_noderelated_from_contact_pair(np, nnode, ndlocal, count_lagrange, permission, &
256  & necessary_to_insert_node, list_noderelated_org, list_noderelated, countnon0lu_node, countnon0lu_lagrange )
257  enddo
258  enddo
259 
260  enddo
261 
262  end subroutine getnewlistofrelatednodesandlagrangemultipliers
263 
265  subroutine fstr_copy_lagrange_contact(fstrSOLID,hecLagMAT)
266 
267  type(fstr_solid) :: fstrsolid
268  type(hecmwst_matrix_lagrange) :: heclagmat
269  integer (kind=kint) :: id_lagrange, algtype, i, j, k, nlag
270 
271  do i = 1, fstrsolid%n_contacts
272 
273  algtype = fstrsolid%contacts(i)%algtype
274  nlag = fstr_get_num_lagrange_pernode(algtype)
275 
276  do j = 1, size(fstrsolid%contacts(i)%slave)
277  id_lagrange = fstrsolid%contacts(i)%states(j)%id_lagrange
278  if( id_lagrange == 0 ) cycle
279  do k=1,nlag
280  heclagmat%Lagrange(id_lagrange+k-1)=fstrsolid%contacts(i)%states(j)%multiplier(k)
281  enddo
282  enddo
283  enddo
284 
285  do i = 1, fstrsolid%n_embeds
286  nlag = 3
287  do j = 1, size(fstrsolid%embeds(i)%slave)
288  id_lagrange = fstrsolid%embeds(i)%states(j)%id_lagrange
289  if( id_lagrange == 0 ) cycle
290  do k=1,nlag
291  heclagmat%Lagrange(id_lagrange+k-1)=fstrsolid%embeds(i)%states(j)%multiplier(k)
292  enddo
293  enddo
294  enddo
295 
296  end subroutine fstr_copy_lagrange_contact
297 
299  logical function fstr_is_matrixstruct_symmetric(fstrSOLID,hecMESH)
300 
301  type(fstr_solid ) :: fstrsolid
302  type(hecmwst_local_mesh) :: hecmesh
303  integer (kind=kint) :: is_in_contact
304 
305  is_in_contact = 0
306  if( fstrsolid%n_contacts>0 ) then
307  if( any(fstrsolid%contacts(:)%fcoeff /= 0.0d0) ) is_in_contact = 1
308  endif
309  call hecmw_allreduce_i1(hecmesh, is_in_contact, hecmw_max)
310  if( is_in_contact == 0 .and. hecmesh%n_dof /= 4 .and. fstr_is_tangent_symmetric(fstrsolid,hecmesh) ) then
312  else
314  endif
315 
316  end function fstr_is_matrixstruct_symmetric
317 
319  logical function fstr_is_contactalag_symmetric(fstrSOLID,hecMESH)
320 
321  type(fstr_solid ) :: fstrsolid
322  type(hecmwst_local_mesh) :: hecmesh
323  integer (kind=kint) :: is_unsymmetric
324 
325  ! the ALagrange contact terms are symmetric while the friction cone radius stays frozen
326  ! at the multiplier; !CONTACT_ALGO, FRICTION_CONE=FOLLOW clears contact%symmetric and
327  ! the tangent then carries the coupling block of getContactStiffness_Alag
328  is_unsymmetric = 0
329  if( fstrsolid%n_contacts>0 ) then
330  if( any( fstrsolid%contacts(:)%fcoeff /= 0.0d0 .and. .not.fstrsolid%contacts(:)%symmetric ) ) is_unsymmetric = 1
331  endif
332  call hecmw_allreduce_i1(hecmesh, is_unsymmetric, hecmw_max)
333  fstr_is_contactalag_symmetric = ( is_unsymmetric == 0 ) .and. fstr_is_tangent_symmetric(fstrsolid,hecmesh)
334 
335  end function fstr_is_contactalag_symmetric
336 
338  logical function fstr_is_tangent_symmetric(fstrSOLID,hecMESH)
339 
340  type(fstr_solid ) :: fstrsolid
341  type(hecmwst_local_mesh) :: hecmesh
342  integer (kind=kint) :: is_unsymmetric, i, ytype, nn
343 
344  ! non-associated flow (dilatancy angle psi /= friction angle phi) makes the consistent
345  ! tangent unsymmetric; when psi is omitted the parser stores psi=phi, so the exact
346  ! comparison below classifies that case as associated (symmetric)
347  is_unsymmetric = 0
348  if( associated(fstrsolid%materials) ) then
349  do i = 1, size(fstrsolid%materials)
350  ytype = getyieldfunction( fstrsolid%materials(i)%mtype )
351  if( ytype == 1 ) then ! Mohr-Coulomb: PLCONST3=phi, PLCONST4=psi
352  if( fstrsolid%materials(i)%variables(m_plconst3) /= fstrsolid%materials(i)%variables(m_plconst4) ) &
353  is_unsymmetric = 1
354  elseif( ytype == 2 ) then ! Drucker-Prager: PLCONST3=eta(phi), PLCONST5=etabar(psi)
355  if( fstrsolid%materials(i)%variables(m_plconst3) /= fstrsolid%materials(i)%variables(m_plconst5) ) &
356  is_unsymmetric = 1
357  endif
358  enddo
359  endif
360  ! Finite-rotation UL shells have an unsymmetric tangent even for elastic materials.
361  if( associated(fstrsolid%elements) ) then
362  do i = 1, hecmesh%n_elem
363  if( .not. associated(fstrsolid%elements(i)%gausses) ) cycle
364  if( fstrsolid%elements(i)%gausses(1)%pMaterial%nlgeom_flag /= updatelag ) cycle
365  nn = hecmesh%elem_node_index(i) - hecmesh%elem_node_index(i-1)
366  if( fstr_uses_finite_rotation_kinematics(hecmesh%elem_type(i), nn, &
367  fstrsolid%elements(i)%gausses(1)%pMaterial) ) then
368  is_unsymmetric = 1
369  exit
370  endif
371  enddo
372  endif
373  call hecmw_allreduce_i1(hecmesh, is_unsymmetric, hecmw_max)
374  fstr_is_tangent_symmetric = (is_unsymmetric == 0)
375 
376  end function fstr_is_tangent_symmetric
377 
379  subroutine fstr_set_lagrange_diagonal(hecLagMAT, ilag, value)
380  type(hecmwst_matrix_lagrange), intent(inout) :: heclagmat
381  integer(kind=kint), intent(in) :: ilag
382  real(kind=kreal), intent(in) :: value
383 
384  if (ilag < 1 .or. ilag > heclagmat%num_lagrange) then
385  write(*,*) 'Error in fstr_set_lagrange_diagonal: invalid Lagrange multiplier index', ilag
386  stop
387  endif
388 
389  if (.not. associated(heclagmat%D_lagrange)) then
390  write(*,*) 'Error in fstr_set_lagrange_diagonal: D_lagrange not allocated'
391  stop
392  endif
393 
394  heclagmat%D_lagrange(ilag) = value
395 
396  end subroutine fstr_set_lagrange_diagonal
397 
399  real(kind=kreal) function fstr_get_lagrange_diagonal(hecLagMAT, ilag)
400  type(hecmwst_matrix_lagrange), intent(in) :: heclagmat
401  integer(kind=kint), intent(in) :: ilag
402 
403  if (ilag < 1 .or. ilag > heclagmat%num_lagrange) then
404  write(*,*) 'Error in fstr_get_lagrange_diagonal: invalid Lagrange multiplier index', ilag
406  return
407  endif
408 
409  if (.not. associated(heclagmat%D_lagrange)) then
410  write(*,*) 'Error in fstr_get_lagrange_diagonal: D_lagrange not allocated'
412  return
413  endif
414 
415  fstr_get_lagrange_diagonal = heclagmat%D_lagrange(ilag)
416 
417  end function fstr_get_lagrange_diagonal
418 
419 
420  subroutine getnewlistofrelatednodesandlagrangemultipliers_ss( &
421  & cstep, contact_algo, np, fstrSOLID, countNon0LU_node, countNon0LU_lagrange, list_nodeRelated )
422  integer(kind=kint),intent(in) :: cstep
423  integer(kind=kint),intent(in) :: contact_algo
424  integer(kind=kint),intent(in) :: np
425  type(fstr_solid),intent(in) :: fstrsolid
426  integer(kind=kint), intent(inout) :: countnon0lu_node, countnon0lu_lagrange
427  type(noderelated), pointer, intent(inout) :: list_noderelated(:)
428  integer(kind=kint) :: grpid
429  integer(kind=kint) :: ctsurf, nsurf
430  integer(kind=kint) :: i, j, m
431  integer(kind=kint) :: g, unique_count
432  integer(kind=kint) :: maplist(max_n_intp), master_idxs(max_n_intp)
433  real(kind=kreal) :: fcoeff
434  logical :: necessary_to_insert_node
435 
436  do i = 1, fstrsolid%n_contacts
437  if( fstrsolid%contacts(i)%method /= contacts2s ) cycle
438  grpid = fstrsolid%contacts(i)%group
439  if( .not. fstr_iscontactactive( fstrsolid, grpid, cstep ) ) cycle
440 
441  fcoeff = fstrsolid%contacts(i)%fcoeff
442  necessary_to_insert_node = ( fcoeff /= 0.0d0 .or. contact_algo == kcaalagrange )
443 
444  do j = 1, size(fstrsolid%contacts(i)%slave_surf)
445  if( fstrsolid%contacts(i)%slave_surf(j)%state == contactfree ) cycle
446 
447  if( contact_algo == kcaalagrange ) then
448  ! ALagrange SS: register sparsity once per unique (slave_surf, master) pair.
449  ! sparsity_expansion == SPARSITY_NONE: current master element only (matrix rebuilt on contact2neighbor)
450  ! sparsity_expansion == SPARSITY_NEIGHBOR: current + neighbor master elements (matrix rebuilt only on contact2beyond)
451  call get_unique_map( fstrsolid%contacts(i)%slave_surf(j), maplist, master_idxs, unique_count )
452  do g = 1, unique_count
453  ctsurf = master_idxs(g)
454  ! Register current master element
455  call register_pair_to_sparsity( np, fstrsolid%contacts(i)%slave_surf(j)%nodes, &
456  fstrsolid%contacts(i)%master(ctsurf), necessary_to_insert_node, &
457  countnon0lu_node, countnon0lu_lagrange, list_noderelated )
458 
459  ! SPARSITY_NEIGHBOR: also register neighbor master elements
460  if( fstrsolid%contacts(i)%sparsity_expansion == sparsity_neighbor ) then
461  do m = 1, fstrsolid%contacts(i)%master(ctsurf)%n_neighbor
462  nsurf = fstrsolid%contacts(i)%master(ctsurf)%neighbor(m)
463  call register_pair_to_sparsity( np, fstrsolid%contacts(i)%slave_surf(j)%nodes, &
464  fstrsolid%contacts(i)%master(nsurf), necessary_to_insert_node, &
465  countnon0lu_node, countnon0lu_lagrange, list_noderelated )
466  enddo
467  endif
468  enddo
469  endif
470  enddo
471  enddo
472 
473  end subroutine getnewlistofrelatednodesandlagrangemultipliers_ss
474 
478  subroutine register_pair_to_sparsity( np, slave_nodes, master_surf, &
479  & necessary_to_insert_node, countNon0LU_node, countNon0LU_lagrange, list_nodeRelated )
480  integer(kind=kint), intent(in) :: np
481  integer(kind=kint), intent(in) :: slave_nodes(:)
482  type(tsurfelement), intent(in) :: master_surf
483  logical, intent(in) :: necessary_to_insert_node
484  integer(kind=kint), intent(inout) :: countnon0lu_node, countnon0lu_lagrange
485  type(noderelated), pointer, intent(inout) :: list_noderelated(:)
486 
487  integer(kind=kint) :: nnode_s, nnode_m, l, m, idx, nnode_pair, etype
488  integer(kind=kint) :: ndlocal(2*l_max_surface_node + 1)
489 
490  etype = master_surf%etype
491  if( etype/=fe_tri3n .and. etype/=fe_quad4n ) stop " ##Error: This element type is not supported in contact analysis !!! "
492  nnode_s = size(slave_nodes)
493  nnode_m = size(master_surf%nodes)
494  do l = 1, nnode_s
495  ndlocal(1) = slave_nodes(l)
496  ! ndLocal: slave_l + other_slave_nodes + master_nodes
497  idx = 1
498  do m = 1, nnode_s
499  if( m == l ) cycle
500  idx = idx + 1
501  ndlocal(idx) = slave_nodes(m)
502  enddo
503  ndlocal(idx+1:idx+nnode_m) = master_surf%nodes(:)
504  nnode_pair = nnode_s - 1 + nnode_m
505  ! mortar pairs have no Lagrange row: 0 keeps insert_lagrange out of the reservation
506  call hecmw_ass_noderelated_from_contact_pair( np, nnode_pair, ndlocal, 0, permission, &
507  & necessary_to_insert_node, list_noderelated_org, list_noderelated, countnon0lu_node, countnon0lu_lagrange )
508  enddo
509  end subroutine register_pair_to_sparsity
510 
534  logical function fstr_s2s_profile_needs_refresh( cstep, contact_algo, fstrSOLID, conMAT )
535  integer(kind=kint), intent(in) :: cstep
536  integer(kind=kint), intent(in) :: contact_algo
537  type(fstr_solid), intent(in) :: fstrsolid
538  type(hecmwst_matrix), intent(in) :: conmat
539 
540  integer(kind=kint) :: i, j, g, ctsurf, grpid, unique_count
541  integer(kind=kint) :: maplist(max_n_intp), master_idxs(max_n_intp)
542 
544  if( contact_algo /= kcaalagrange ) return
545 
546  do i = 1, fstrsolid%n_contacts
547  if( fstrsolid%contacts(i)%method /= contacts2s ) cycle
548  grpid = fstrsolid%contacts(i)%group
549  if( .not. fstr_iscontactactive( fstrsolid, grpid, cstep ) ) cycle
550 
551  do j = 1, size(fstrsolid%contacts(i)%slave_surf)
552  if( fstrsolid%contacts(i)%slave_surf(j)%state == contactfree ) cycle
553 
554  call get_unique_map( fstrsolid%contacts(i)%slave_surf(j), maplist, master_idxs, unique_count )
555  do g = 1, unique_count
556  ctsurf = master_idxs(g)
557  if( .not. pair_cross_profile_complete( fstrsolid%contacts(i)%slave_surf(j)%nodes, &
558  & fstrsolid%contacts(i)%master(ctsurf), conmat ) ) then
560  return
561  endif
562  enddo
563  enddo
564  enddo
565  end function fstr_s2s_profile_needs_refresh
566 
570  logical function pair_cross_profile_complete( slave_nodes, master_surf, conMAT )
571  integer(kind=kint), intent(in) :: slave_nodes(:)
572  type(tsurfelement), intent(in) :: master_surf
573  type(hecmwst_matrix), intent(in) :: conmat
574 
575  integer(kind=kint) :: s, m
576 
577  pair_cross_profile_complete = .true.
578  do s = 1, size(slave_nodes)
579  do m = 1, size(master_surf%nodes)
580  if( .not. hecmw_mat_profile_has_node( conmat, slave_nodes(s), master_surf%nodes(m) ) ) then
581  pair_cross_profile_complete = .false.
582  return
583  endif
584  enddo
585  enddo
586  end function pair_cross_profile_complete
587 
588 end module fstr_matrix_con_contact
This module encapsulate the basic functions of all elements provide by this software.
Definition: element.f90:43
integer, parameter fe_tri3n
Definition: element.f90:70
integer, parameter fe_quad4n
Definition: element.f90:73
This module provides functions of reconstructing.
subroutine, public fstr_set_lagrange_diagonal(hecLagMAT, ilag, value)
Set diagonal component value for specified Lagrange multiplier.
integer(kind=kint) function, public fstr_get_num_lagrange_pernode(algtype)
subroutine, public fstr_mat_con_contact(cstep, contact_algo, hecMAT, fstrSOLID, hecLagMAT, conMAT, is_contact_active_flag)
this subroutine reconstructs node-based (stiffness) matrix structure \corresponding to contact state
logical function, public fstr_s2s_profile_needs_refresh(cstep, contact_algo, fstrSOLID, conMAT)
S2S mortar profile-invariant check (read-only companion to the reservation in getNewListOFrelatednode...
logical function, public fstr_is_tangent_symmetric(fstrSOLID, hecMESH)
this function judges whether the material and element tangents are symmetric
logical function, public fstr_is_contactalag_symmetric(fstrSOLID, hecMESH)
this function judges whether the ALagrange contact tangent is symmetric or not
subroutine, public fstr_save_originalmatrixstructure(hecMAT)
This subroutine saves original matrix structure constructed originally by hecMW_matrix.
logical function, public fstr_is_matrixstruct_symmetric(fstrSOLID, hecMESH)
this function judges whether sitiffness matrix is symmetric or not
real(kind=kreal) function, public fstr_get_lagrange_diagonal(hecLagMAT, ilag)
Get diagonal component value for specified Lagrange multiplier.
logical function, public hecmw_mat_profile_has_node(hecMAT, inod, jnod)
Read-only companion to hecmw_mat_add_node: report whether the (inod, jnod) block exists in the matrix...
Contact damping module for CONTACTNEAR state.
pure logical function, public is_damping_enabled(contact)
Check if damping is enabled for a contact pair.
Alag method implementations for contact element calculations.
subroutine, public get_unique_map(sSurf, maplist, master_idxs, unique_count)
Shared finite-rotation nodal kinematics and rotation algebra.
logical function, public fstr_uses_finite_rotation_kinematics(etype, nn, material)
This module defines common data and basic structures for analysis.
Definition: m_fstr.F90:15
logical function fstr_isembedactive(fstrSOLID, nbc, cstep)
Definition: m_fstr.F90:1286
logical function fstr_iscontactactive(fstrSOLID, nbc, cstep)
Definition: m_fstr.F90:1276
integer(kind=kint), parameter kcaslagrange
contact analysis algorithm
Definition: m_fstr.F90:62
integer(kind=kint), parameter kcaalagrange
Definition: m_fstr.F90:63