FrontISTR  5.7.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
13 
14  implicit none
15  private
17  public :: hecmwst_matrix_lagrange
19  public :: fstr_mat_con_contact
21 
22  integer(kind=kint), save :: NPL_org, NPU_org
23  type(nodeRelated), pointer, save :: list_nodeRelated_org(:) => null()
24 
25  type(nodeRelated), pointer :: list_nodeRelated(:) => null()
26 
27  logical :: permission = .false.
28 
29 contains
30 
31  integer(kind=kint) function fstr_get_num_lagrange_pernode(algtype)
32  integer(kind=kint) :: algtype
33  if( algtype == contactsslid .or. algtype == contactfslid ) then
35  else if( algtype == contacttied ) then
37  endif
38  end function
39 
41  subroutine fstr_save_originalmatrixstructure(hecMAT)
42 
43  type(hecmwst_matrix) :: hecmat
44 
45  if( associated(list_noderelated_org) ) return
46  call hecmw_construct_noderelated_from_hecmat(hecmat, npl_org, npu_org, list_noderelated_org)
47 
49 
52  subroutine fstr_mat_con_contact(cstep,contact_algo,hecMAT,fstrSOLID,hecLagMAT,infoCTChange,conMAT,is_contact_active)
53 
54  integer(kind=kint) :: cstep
55  integer(kind=kint) :: contact_algo
56  type(hecmwst_matrix) :: hecmat
57  type(fstr_solid) :: fstrsolid
58  type(hecmwst_matrix_lagrange) :: heclagmat
59  type(fstr_info_contactchange) :: infoctchange
60 
61  integer(kind=kint) :: num_lagrange
62  integer(kind=kint) :: countnon0lu_node, countnon0lu_lagrange
63  integer(kind=kint) :: numnon0_node, numnon0_lagrange
65  type (hecmwst_matrix) :: conmat
66  logical, intent(in) :: is_contact_active
67 
68  integer(kind=kint) :: i, j, grpid
69  integer(kind=kint) :: nlag
70 
71  num_lagrange = 0
72  if( contact_algo == kcaslagrange ) then
73  do i = 1, fstrsolid%n_contacts
74  grpid = fstrsolid%contacts(i)%group
75  if( .not. fstr_iscontactactive( fstrsolid, grpid, cstep ) ) cycle
76  nlag = fstr_get_num_lagrange_pernode(fstrsolid%contacts(i)%algtype)
77  do j = 1, size(fstrsolid%contacts(i)%slave)
78  if( fstrsolid%contacts(i)%states(j)%state == contactfree ) cycle
79  num_lagrange = num_lagrange + nlag
80  enddo
81  enddo
82 
83  do i = 1, fstrsolid%n_embeds
84  grpid = fstrsolid%embeds(i)%group
85  if( .not. fstr_iscontactactive( fstrsolid, grpid, cstep ) ) cycle
86  nlag = 3
87  do j = 1, size(fstrsolid%embeds(i)%slave)
88  if( fstrsolid%embeds(i)%states(j)%state == contactfree ) cycle
89  num_lagrange = num_lagrange + nlag
90  enddo
91  enddo
92  endif
93 
94  ! Get original list of related nodes
95  call hecmw_init_noderelated_from_org(hecmat%NP,num_lagrange,is_contact_active,list_noderelated_org,list_noderelated)
96 
97  ! Construct new list of related nodes and Lagrange multipliers
98  countnon0lu_node = npl_org + npu_org
99  countnon0lu_lagrange = 0
100  if( is_contact_active ) call getnewlistofrelatednodesandlagrangemultipliers(cstep,contact_algo, &
101  & hecmat%NP,fstrsolid,countnon0lu_node,countnon0lu_lagrange,list_noderelated)
102 
103  ! Construct new matrix structure(hecMAT&hecLagMAT)
104  numnon0_node = countnon0lu_node/2
105  numnon0_lagrange = countnon0lu_lagrange/2
106  call hecmw_construct_hecmat_from_noderelated(hecmat%N, hecmat%NP, hecmat%NDOF, &
107  & numnon0_node, num_lagrange, list_noderelated, hecmat)
108  call hecmw_construct_hecmat_from_noderelated(hecmat%N, hecmat%NP, hecmat%NDOF, &
109  & numnon0_node, num_lagrange, list_noderelated, conmat)
110  if( contact_algo == kcaslagrange ) call hecmw_construct_heclagmat_from_noderelated(hecmat%NP, &
111  & hecmat%NDOF, num_lagrange, numnon0_lagrange, is_contact_active, list_noderelated, heclagmat)
112  call hecmw_finalize_noderelated(list_noderelated)
113 
114  ! Copy Lagrange multipliers
115  if( is_contact_active .and. contact_algo == kcaslagrange ) &
116  call fstr_copy_lagrange_contact(fstrsolid,heclagmat)
117 
118  end subroutine fstr_mat_con_contact
119 
121  subroutine getnewlistofrelatednodesandlagrangemultipliers( &
122  & cstep, contact_algo, np, fstrSOLID, countNon0LU_node, countNon0LU_lagrange, list_nodeRelated )
123  integer(kind=kint),intent(in) :: cstep
124  integer(kind=kint),intent(in) :: contact_algo
125  integer(kind=kint),intent(in) :: np
126  type(fstr_solid),intent(in) :: fstrsolid
127  integer(kind=kint), intent(inout) :: countnon0lu_node, countnon0lu_lagrange
128  type(noderelated), pointer, intent(inout) :: list_noderelated(:)
129 
130  integer(kind=kint) :: grpid
131  integer(kind=kint) :: count_lagrange
132  integer(kind=kint) :: ctsurf, etype, nnode, ndlocal(l_max_surface_node + 1)
133  integer(kind=kint) :: i, j, k, nlag, algtype
134  real(kind=kreal) :: fcoeff
135  logical :: necessary_to_insert_node
136 
137  count_lagrange = 0
138  do i = 1, fstrsolid%n_contacts
139 
140  grpid = fstrsolid%contacts(i)%group
141  if( .not. fstr_iscontactactive( fstrsolid, grpid, cstep ) ) cycle
142 
143  fcoeff = fstrsolid%contacts(i)%fcoeff
144  necessary_to_insert_node = ( fcoeff /= 0.0d0 .or. contact_algo == kcaalagrange )
145 
146  algtype = fstrsolid%contacts(i)%algtype
147  nlag = fstr_get_num_lagrange_pernode(algtype)
148  if( contact_algo == kcaalagrange ) nlag = 1
149  if( algtype == contacttied ) permission = .true.
150 
151  do j = 1, size(fstrsolid%contacts(i)%slave)
152 
153  if( fstrsolid%contacts(i)%states(j)%state == contactfree ) cycle
154  ctsurf = fstrsolid%contacts(i)%states(j)%surface
155  etype = fstrsolid%contacts(i)%master(ctsurf)%etype
156  if( etype/=fe_tri3n .and. etype/=fe_quad4n ) &
157  stop " ##Error: This element type is not supported in contact analysis !!! "
158  nnode = size(fstrsolid%contacts(i)%master(ctsurf)%nodes)
159  ndlocal(1) = fstrsolid%contacts(i)%slave(j)
160  ndlocal(2:nnode+1) = fstrsolid%contacts(i)%master(ctsurf)%nodes(1:nnode)
161 
162  do k=1,nlag
163  if( contact_algo == kcaslagrange ) count_lagrange = count_lagrange + 1
164  call hecmw_ass_noderelated_from_contact_pair(np, nnode, ndlocal, count_lagrange, permission, &
165  & necessary_to_insert_node, list_noderelated_org, list_noderelated, countnon0lu_node, countnon0lu_lagrange )
166  enddo
167  enddo
168 
169  enddo
170 
171  do i = 1, fstrsolid%n_embeds
172 
173  grpid = fstrsolid%embeds(i)%group
174  if( .not. fstr_isembedactive( fstrsolid, grpid, cstep ) ) cycle
175 
176  necessary_to_insert_node = ( contact_algo == kcaalagrange )
177 
178  nlag = 3
179  if( contact_algo == kcaalagrange ) nlag = 1
180  permission = .true.
181 
182  do j = 1, size(fstrsolid%embeds(i)%slave)
183 
184  if( fstrsolid%embeds(i)%states(j)%state == contactfree ) cycle
185  ctsurf = fstrsolid%embeds(i)%states(j)%surface
186  etype = fstrsolid%embeds(i)%master(ctsurf)%etype
187  nnode = size(fstrsolid%embeds(i)%master(ctsurf)%nodes)
188  ndlocal(1) = fstrsolid%embeds(i)%slave(j)
189  ndlocal(2:nnode+1) = fstrsolid%embeds(i)%master(ctsurf)%nodes(1:nnode)
190 
191  do k=1,nlag
192  if( contact_algo == kcaslagrange ) count_lagrange = count_lagrange + 1
193  call hecmw_ass_noderelated_from_contact_pair(np, nnode, ndlocal, count_lagrange, permission, &
194  & necessary_to_insert_node, list_noderelated_org, list_noderelated, countnon0lu_node, countnon0lu_lagrange )
195  enddo
196  enddo
197 
198  enddo
199 
200  end subroutine getnewlistofrelatednodesandlagrangemultipliers
201 
203  subroutine fstr_copy_lagrange_contact(fstrSOLID,hecLagMAT)
204 
205  type(fstr_solid) :: fstrsolid
206  type(hecmwst_matrix_lagrange) :: heclagmat
207  integer (kind=kint) :: id_lagrange, algtype, i, j, k, nlag
208 
209  id_lagrange = 0
210 
211  do i = 1, fstrsolid%n_contacts
212 
213  algtype = fstrsolid%contacts(i)%algtype
214  nlag = fstr_get_num_lagrange_pernode(algtype)
215 
216  do j = 1, size(fstrsolid%contacts(i)%slave)
217  if( fstrsolid%contacts(i)%states(j)%state == contactfree ) cycle
218  do k=1,nlag
219  id_lagrange = id_lagrange + 1
220  heclagmat%Lagrange(id_lagrange)=fstrsolid%contacts(i)%states(j)%multiplier(k)
221  enddo
222  enddo
223  enddo
224 
225  do i = 1, fstrsolid%n_embeds
226  nlag = 3
227  do j = 1, size(fstrsolid%embeds(i)%slave)
228  if( fstrsolid%embeds(i)%states(j)%state == contactfree ) cycle
229  do k=1,nlag
230  id_lagrange = id_lagrange + 1
231  heclagmat%Lagrange(id_lagrange)=fstrsolid%embeds(i)%states(j)%multiplier(k)
232  enddo
233  enddo
234  enddo
235 
236  end subroutine fstr_copy_lagrange_contact
237 
239  logical function fstr_is_matrixstruct_symmetric(fstrSOLID,hecMESH)
240 
241  type(fstr_solid ) :: fstrsolid
242  type(hecmwst_local_mesh) :: hecmesh
243  integer (kind=kint) :: is_in_contact
244 
245  is_in_contact = 0
246  if( fstrsolid%n_contacts>0 ) then
247  if( any(fstrsolid%contacts(:)%fcoeff /= 0.0d0) ) is_in_contact = 1
248  endif
249  call hecmw_allreduce_i1(hecmesh, is_in_contact, hecmw_max)
250  fstr_is_matrixstruct_symmetric = (is_in_contact == 0)
251 
252  end function fstr_is_matrixstruct_symmetric
253 
254 
255 end module fstr_matrix_con_contact
elementinfo::fe_quad4n
integer, parameter fe_quad4n
Definition: element.f90:72
fstr_matrix_con_contact::fstr_get_num_lagrange_pernode
integer(kind=kint) function, public fstr_get_num_lagrange_pernode(algtype)
Definition: fstr_mat_con_contact.f90:32
elementinfo::fe_tri3n
integer, parameter fe_tri3n
Definition: element.f90:69
m_fstr::fstr_solid
Definition: m_fstr.f90:238
fstr_matrix_con_contact::fstr_is_matrixstruct_symmetric
logical function, public fstr_is_matrixstruct_symmetric(fstrSOLID, hecMESH)
this function judges whether sitiffness matrix is symmetric or not
Definition: fstr_mat_con_contact.f90:240
m_fstr::fstr_iscontactactive
logical function fstr_iscontactactive(fstrSOLID, nbc, cstep)
Definition: m_fstr.f90:1052
fstr_matrix_con_contact::fstr_save_originalmatrixstructure
subroutine, public fstr_save_originalmatrixstructure(hecMAT)
This subroutine saves original matrix structure constructed originally by hecMW_matrix.
Definition: fstr_mat_con_contact.f90:42
m_fstr::kcaalagrange
integer(kind=kint), parameter kcaalagrange
Definition: m_fstr.f90:60
m_fstr::kcaslagrange
integer(kind=kint), parameter kcaslagrange
contact analysis algorithm
Definition: m_fstr.f90:59
m_fstr
This module defines common data and basic structures for analysis.
Definition: m_fstr.f90:15
elementinfo
This module encapsulate the basic functions of all elements provide by this software.
Definition: element.f90:43
fstr_matrix_con_contact
This module provides functions of reconstructing.
Definition: fstr_mat_con_contact.f90:9
fstr_matrix_con_contact::fstr_mat_con_contact
subroutine, public fstr_mat_con_contact(cstep, contact_algo, hecMAT, fstrSOLID, hecLagMAT, infoCTChange, conMAT, is_contact_active)
this subroutine reconstructs node-based (stiffness) matrix structure \corresponding to contact state
Definition: fstr_mat_con_contact.f90:53
m_fstr::fstr_isembedactive
logical function fstr_isembedactive(fstrSOLID, nbc, cstep)
Definition: m_fstr.f90:1062