FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
fstr_contact_output.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 !-------------------------------------------------------------------------------
12  use hecmw
13  use m_fstr
14  use mcontactdef
16  implicit none
17 
19  public :: initialize_embed_vectors
21  public :: calc_contact_area
24 
25  private :: calc_nodalarea_surfelement
26 
27 contains
28 
29  subroutine initialize_contact_output_vectors(fstrSOLID,hecMAT)
30  type(fstr_solid) :: fstrsolid
31  type(hecmwst_matrix) :: hecmat
32 
33  if( .not. associated(fstrsolid%CONT_NFORCE) ) then
34  allocate( fstrsolid%CONT_NFORCE(hecmat%NP*3) )
35  fstrsolid%CONT_NFORCE(:) = 0.d0
36  end if
37 
38  if( .not. associated(fstrsolid%CONT_FRIC) ) then
39  allocate( fstrsolid%CONT_FRIC(hecmat%NP*3) )
40  fstrsolid%CONT_FRIC(:) = 0.d0
41  end if
42 
43  if( .not. associated(fstrsolid%CONT_RELVEL) ) then
44  allocate( fstrsolid%CONT_RELVEL(hecmat%NP*3) )
45  fstrsolid%CONT_RELVEL(:) = 0.d0
46  end if
47 
48  if( .not. associated(fstrsolid%CONT_STATE) ) then
49  allocate( fstrsolid%CONT_STATE(hecmat%NP*1) )
50  fstrsolid%CONT_STATE(:) = 0.d0
51  end if
52 
53  if( .not. associated(fstrsolid%CONT_AREA) ) then
54  allocate( fstrsolid%CONT_AREA(hecmat%NP) )
55  fstrsolid%CONT_AREA(:) = 0.d0
56  end if
57 
58  if( .not. associated(fstrsolid%CONT_NTRAC) ) then
59  allocate( fstrsolid%CONT_NTRAC(hecmat%NP*3) )
60  fstrsolid%CONT_NTRAC(:) = 0.d0
61  end if
62 
63  if( .not. associated(fstrsolid%CONT_FTRAC) ) then
64  allocate( fstrsolid%CONT_FTRAC(hecmat%NP*3) )
65  fstrsolid%CONT_FTRAC(:) = 0.d0
66  end if
67 
68  end subroutine
69 
70  subroutine initialize_embed_vectors(fstrSOLID,hecMAT)
71  type(fstr_solid) :: fstrsolid
72  type(hecmwst_matrix) :: hecmat
73 
74  if( .not. associated(fstrsolid%EMBED_NFORCE) ) then
75  allocate( fstrsolid%EMBED_NFORCE(hecmat%NP*3) )
76  fstrsolid%EMBED_NFORCE(:) = 0.d0
77  end if
78  end subroutine
79 
80  subroutine setup_contact_elesurf_for_area( cstep, hecMESH, fstrSOLID )
81  integer(kind=kint), intent(in) :: cstep
82  type( hecmwst_local_mesh ), intent(in) :: hecmesh
83  type(fstr_solid), intent(inout) :: fstrsolid
84 
85  integer(kind=kint) :: i, j, k, sgrp_id, is, ie, eid, sid, n_cdsurfs
86  logical, pointer :: cdef_surf(:,:)
87 
88  if( associated(fstrsolid%CONT_SGRP_ID) ) deallocate(fstrsolid%CONT_SGRP_ID)
89 
90  allocate(cdef_surf(l_max_elem_surf,hecmesh%n_elem))
91  cdef_surf(:,:) = .false.
92 
93  ! label contact defined surfaces
94  n_cdsurfs = 0
95  do i=1, fstrsolid%n_contacts
96  !grpid = fstrSOLID%contacts(i)%group
97  !if( .not. fstr_isContactActive( fstrSOLID, grpid, cstep ) ) then
98  ! call clear_contact_state(fstrSOLID%contacts(i)); cycle
99  !endif
100 
101  do k=1,2 !slave,master
102  if( k==1 ) then !slave
103  sgrp_id = fstrsolid%contacts(i)%surf_id1_sgrp
104  else if( k==2 ) then !master
105  sgrp_id = fstrsolid%contacts(i)%surf_id2
106  end if
107 
108  if( sgrp_id <= 0 ) cycle
109 
110  is = hecmesh%surf_group%grp_index(sgrp_id-1) + 1
111  ie = hecmesh%surf_group%grp_index(sgrp_id )
112  do j=is,ie
113  eid = hecmesh%surf_group%grp_item(2*j-1)
114  sid = hecmesh%surf_group%grp_item(2*j)
115  ! only internal and boundary element should be added
116  if( .not. cdef_surf(sid,eid) ) n_cdsurfs = n_cdsurfs + 1
117  cdef_surf(sid,eid) = .true.
118  enddo
119  end do
120  enddo
121 
122  !gather info of contact defined surfaces
123  allocate(fstrsolid%CONT_SGRP_ID(2*n_cdsurfs))
124  n_cdsurfs = 0
125  do i=1,hecmesh%n_elem
126  do j=1,l_max_elem_surf
127  if( cdef_surf(j,i) ) then
128  n_cdsurfs = n_cdsurfs + 1
129  fstrsolid%CONT_SGRP_ID(2*n_cdsurfs-1) = i
130  fstrsolid%CONT_SGRP_ID(2*n_cdsurfs ) = j
131  endif
132  end do
133  end do
134  deallocate(cdef_surf)
135 
136  end subroutine
137 
138  subroutine calc_contact_area( hecMESH, fstrSOLID, flag )
139  type( hecmwst_local_mesh ), intent(in) :: hecmesh
140  type(fstr_solid), intent(inout) :: fstrsolid
141  integer(kind=kint), intent(in) :: flag
142 
143  integer(kind=kint), parameter :: ndof=3
144  integer(kind=kint) :: i, isuf, icel, sid, etype, nn, is, idx
145  integer(kind=kint) :: ndlocal(l_max_elem_node)
146  real(kind=kreal), allocatable :: coord(:)
147  real(kind=kreal) :: ecoord(ndof,l_max_elem_node), vect(l_max_elem_node)
148 
149  fstrsolid%CONT_AREA(:) = 0.d0
150 
151  if( .not. associated(fstrsolid%CONT_SGRP_ID) ) return
152 
153  allocate(coord(ndof*hecmesh%n_node))
154  do i=1,ndof*hecmesh%n_node
155  coord(i) = hecmesh%node(i)+fstrsolid%unode(i)
156  end do
157  if( flag == 1 ) then
158  do i=1,ndof*hecmesh%n_node
159  coord(i) = coord(i)+fstrsolid%dunode(i)
160  end do
161  end if
162 
163  do isuf=1,size(fstrsolid%CONT_SGRP_ID)/2
164  icel = fstrsolid%CONT_SGRP_ID(2*isuf-1)
165  sid = fstrsolid%CONT_SGRP_ID(2*isuf )
166 
167  etype = hecmesh%elem_type(icel)
168  nn = hecmw_get_max_node(etype)
169  is = hecmesh%elem_node_index(icel-1)
170  ndlocal(1:nn) = hecmesh%elem_node_item (is+1:is+nn)
171 
172  do i=1,nn
173  idx = ndof*(ndlocal(i)-1)
174  ecoord(1:ndof,i) = coord(idx+1:idx+ndof)
175  end do
176 
177  call calc_nodalarea_surfelement( etype, nn, ecoord, sid, vect )
178 
179  do i=1,nn
180  idx = ndlocal(i)
181  fstrsolid%CONT_AREA(idx) = fstrsolid%CONT_AREA(idx) + vect(i)
182  end do
183 
184  end do
185 
186  deallocate(coord)
187  end subroutine
188 
189  subroutine calc_nodalarea_surfelement( etype, nn, ecoord, sid, vect )
190  integer(kind=kint), intent(in) :: etype
191  integer(kind=kint), intent(in) :: nn
192  real(kind=kreal), intent(in) :: ecoord(:,:)
193  integer(kind=kint), intent(in) :: sid
194  real(kind=kreal), intent(out) :: vect(:)
195 
196  integer(kind=kint), parameter :: ndof=3
197  integer(kind=kint) :: nod(l_max_surface_node)
198  integer(kind=kint) :: nsur, stype, ig0, i
199  real(kind=kreal) :: localcoord(2), normal(3), area, wg
200  real(kind=kreal) :: scoord(ndof,l_max_surface_node), h(l_max_surface_node)
201 
202  vect(:) = 0.d0
203 
204  call getsubface( etype, sid, stype, nod )
205  nsur = getnumberofnodes( stype )
206  do i=1,nsur
207  scoord(1:ndof,i) = ecoord(1:ndof,nod(i))
208  end do
209 
210  area = 0.d0
211  do ig0=1,numofquadpoints( stype )
212  call getquadpoint( stype, ig0, localcoord(1:2) )
213  call getshapefunc( stype, localcoord(1:2), h(1:nsur) )
214 
215  wg=getweight( stype, ig0 )
216  ! normal = dx/dr_1 \times dx/dr_2
217  normal(1:3) = surfacenormal( stype, nsur, localcoord(1:2), scoord(1:ndof,1:nsur) )
218  area = area + dsqrt(dot_product(normal,normal))*wg
219  enddo
220  area = area/dble(nsur)
221  do i=1,nsur
222  vect(nod(i)) = area
223  end do
224 
225  end subroutine
226 
227  subroutine fstr_setup_parancon_contactvalue(hecMESH,ndof,vec,vtype)
228  use m_fstr
229  implicit none
230  type(hecmwst_local_mesh), intent(in) :: hecmesh
231  integer(kind=kint), intent(in) :: ndof
232  real(kind=kreal), pointer, intent(inout) :: vec(:)
233  integer(kind=kint), intent(in) :: vtype !1:value, 2:state
234  !
235  integer(kind=kint) :: i,n,i0,n_loc
236  integer(kind=kint) :: offset, pid, lid
237  integer(kind=kint), allocatable :: displs(:)
238  real(kind=kreal), allocatable :: vec_all(:)
239 
240  !
241  n_loc = hecmesh%nn_internal
242  allocate(displs(0:nprocs))
243  displs(:) = 0
244  displs(myrank+1) = n_loc
245  call hecmw_allreduce_i(hecmesh, displs, nprocs+1, hecmw_sum)
246  do i=1,nprocs
247  displs(i) = displs(i-1) + displs(i)
248  end do
249  offset = displs(myrank)
250  n = displs(nprocs)
251 
252  allocate(vec_all(ndof*n))
253 
254  if( vtype == 1 ) then
255  vec_all(:) = 0.d0
256  do i= 1, hecmesh%n_node
257  pid = hecmesh%node_ID(i*2)
258  lid = hecmesh%node_ID(i*2-1)
259  i0 = (displs(pid) + (lid-1))*ndof
260  vec_all(i0+1:i0+ndof) = vec((i-1)*ndof+1:i*ndof)
261  vec((i-1)*ndof+1:i*ndof) = 0.d0
262  enddo
263 
264  call hecmw_allreduce_r(hecmesh, vec_all, n*ndof, hecmw_sum)
265  do i= 1, hecmesh%n_node
266  pid = hecmesh%node_ID(i*2)
267  lid = hecmesh%node_ID(i*2-1)
268  i0 = (displs(pid) + (lid-1))*ndof
269  if (dot_product(vec_all(i0+1:i0+ndof),vec_all(i0+1:i0+ndof)) == 0.d0) cycle
270  vec((i-1)*ndof+1:i*ndof) = vec_all(i0+1:i0+ndof)
271  enddo
272  do i=1,ndof*n_loc
273  vec(i) = vec_all(offset*ndof+i)
274  end do
275  else if( vtype == 2 ) then
276  vec_all(:) = -1000.d0
277  do i= 1, hecmesh%n_node
278  if( vec(i) == 0.d0 ) cycle
279  pid = hecmesh%node_ID(i*2)
280  lid = hecmesh%node_ID(i*2-1)
281  i0 = displs(pid) + lid
282  vec_all(i0) = vec(i)
283  enddo
284 
285  call hecmw_allreduce_r(hecmesh, vec_all, n, hecmw_max)
286  do i= 1, hecmesh%n_node
287  pid = hecmesh%node_ID(i*2)
288  lid = hecmesh%node_ID(i*2-1)
289  i0 = displs(pid) + lid
290  if(vec_all(i0) == -1000.d0) cycle
291  if(vec(i) < vec_all(i0)) vec(i) = vec_all(i0)
292  enddo
293  end if
294 
295  deallocate(displs,vec_all)
296  end subroutine
297 
299  subroutine update_contact_state_vectors( contact, dt, relvel_vec, state_vec )
300  type( tcontact ), intent(in) :: contact
301  real(kind=kreal), intent(in) :: dt
302  real(kind=kreal), intent(inout) :: relvel_vec(:)
303  real(kind=kreal), intent(inout) :: state_vec(:)
304 
305  integer(kind=kint) :: i, slave
306 
307  do i= 1, size(contact%slave)
308  slave = contact%slave(i)
309  if( state_vec(slave) < 0.1d0 .or. contact%states(i)%state > 0 ) &
310  & state_vec(slave) = dble(contact%states(i)%state)
311 
312  if( contact%states(i)%state==contactfree ) cycle ! not in contact
313  if( dt < 1.d-16 ) cycle ! too small delta t
314  relvel_vec(3*slave-2:3*slave) = contact%states(i)%reldisp(1:3)/dt
315  enddo
316 
317  end subroutine update_contact_state_vectors
318 
319 end module m_fstr_contact_output
Definition: hecmw.f90:6
This module provides geometric calculations for contact.
Contact output vector processing (initialization, area calculation, parallel)
subroutine, public fstr_setup_parancon_contactvalue(hecMESH, ndof, vec, vtype)
subroutine, public calc_contact_area(hecMESH, fstrSOLID, flag)
subroutine, public initialize_contact_output_vectors(fstrSOLID, hecMAT)
subroutine, public setup_contact_elesurf_for_area(cstep, hecMESH, fstrSOLID)
subroutine, public initialize_embed_vectors(fstrSOLID, hecMAT)
subroutine, public update_contact_state_vectors(contact, dt, relvel_vec, state_vec)
Update contact state output vectors (CONT_RELVEL, CONT_STATE)
This module defines common data and basic structures for analysis.
Definition: m_fstr.f90:15
integer(kind=kint) myrank
PARALLEL EXECUTION.
Definition: m_fstr.f90:97
integer(kind=kint) nprocs
Definition: m_fstr.f90:98
real(kind=kreal) dt
ANALYSIS CONTROL for NLGEOM and HEAT.
Definition: m_fstr.f90:140
This module manages the data structure for contact calculation.
integer, parameter contactfree
contact state definition
Structure to includes all info needed by contact calculation.