FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
dynamic_mat_ass_bc.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 
8 
9 contains
10 
11 
13  subroutine dynamic_mat_ass_bc(cstep, hecMESH, hecMAT, fstrSOLID ,fstrDYNAMIC, fstrPARAM, hecLagMAT, hecEBC, &
14  t_curr, iter, conMAT)
15  use m_fstr
16  use m_table_dyn
17  use mcontact
18  use m_utilities
19  use hecmw_ebc_defer
20 
21  implicit none
22  integer, intent(in) :: cstep
23  type(hecmwst_matrix) :: hecMAT
24  type(hecmwst_local_mesh) :: hecMESH
25  type(fstr_solid) :: fstrSOLID
26  type(fstr_dynamic) :: fstrDYNAMIC
27  type(fstr_param) :: fstrPARAM
28  type(hecmwst_matrix_lagrange) :: hecLagMAT
29  type(hecmwst_ebc) :: hecEBC
30  real(kind=kreal) :: t_curr
31  integer, optional :: iter
32  type(hecmwst_matrix), optional :: conMAT
33 
34  integer(kind=kint) :: ig0, ig, ityp, NDOF, iS0, iE0, ik, in, idofS, idofE, idof
35 
36  integer(kind=kint) :: flag_u, grpid
37  real(kind=kreal) :: rhs, f_t, f_t1
38 
39  !for rotation
40  integer(kind=kint) :: n_rot, rid, n_nodes
41  type(trotinfo) :: rinfo
42  real(kind=kreal) :: theta, normal(3), direc(3), ccoord(3), cdiff(3), cdiff0(3)
43  real(kind=kreal) :: cdisp(3), cddisp(3)
44  real(kind=kreal) :: rotation_factor
45  !
46  ndof = hecmat%NDOF
47  n_rot = fstrsolid%BOUNDARY_ngrp_rot
48  if( n_rot > 0 ) call fstr_rotinfo_init(n_rot, rinfo)
49 
50  flag_u = 1
51  !C=============================C
52  !C-- implicit dynamic analysis
53  !C=============================C
54  if( fstrdynamic%idx_eqa == 1 ) then
55 
56  do ig0 = 1, fstrsolid%BOUNDARY_ngrp_tot
57  ig = fstrsolid%BOUNDARY_ngrp_ID(ig0)
58  grpid = fstrsolid%BOUNDARY_ngrp_GRPID(ig0)
59  if( .not. fstr_isboundaryactive( fstrsolid, grpid, cstep ) ) cycle
60  rhs = fstrsolid%BOUNDARY_ngrp_val(ig0)
61 
62  if( present(iter) ) then
63  if( iter>1 ) then
64  rhs=0.d0
65  else
66  f_t1 = rhs
67  call fstr_get_amplitude_dyn(hecmesh, fstrsolid, fstrdynamic, ig0, t_curr-fstrdynamic%t_delta, f_t1, flag_u)
68  f_t = rhs
69  call fstr_get_amplitude_dyn(hecmesh, fstrsolid, fstrdynamic, ig0, t_curr, f_t, flag_u)
70  rhs = f_t - f_t1
71  endif
72  else
73  call fstr_get_amplitude_dyn(hecmesh, fstrsolid, fstrdynamic, ig0, t_curr, rhs, flag_u)
74  endif
75 
76  ityp = fstrsolid%BOUNDARY_ngrp_type(ig0)
77  idofs = ityp/10
78  idofe = ityp - idofs*10
79 
80  is0 = hecmesh%node_group%grp_index(ig-1) + 1
81  ie0 = hecmesh%node_group%grp_index(ig )
82 
83  if( fstrsolid%BOUNDARY_ngrp_rotID(ig0) > 0 ) then ! setup rotation information
84  rid = fstrsolid%BOUNDARY_ngrp_rotID(ig0)
85  if( .not. rinfo%conds(rid)%active ) then
86  rinfo%conds(rid)%active = .true.
87  rinfo%conds(rid)%center_ngrp_id = fstrsolid%BOUNDARY_ngrp_centerID(ig0)
88  rinfo%conds(rid)%torque_ngrp_id = ig
89  endif
90  do idof=idofs,idofe
91  if( idof>ndof ) then
92  rinfo%conds(rid)%vec(idof-ndof) = rhs
93  else
94  rinfo%conds(rid)%vec(idof) = rhs
95  endif
96  enddo
97  cycle
98  endif
99 
100  do ik = is0, ie0
101  in = hecmesh%node_group%grp_item(ik)
102 
103  do idof = idofs, idofe
104  call hecmw_ebc_set(hecebc, in, idof, rhs)
105  if( fstr_is_contact_active() .and. fstrparam%contact_algo == kcaslagrange &
106  .and. fstrparam%nlgeom .and. fstrdynamic%idx_resp == 1 ) then
107  if(present(conmat)) then
108  call hecmw_mat_ass_bc_contactlag(conmat,heclagmat,in,idof,rhs)
109  else
110  call hecmw_mat_ass_bc_contactlag(hecmat,heclagmat,in,idof,rhs)
111  endif
112  endif
113  enddo
114  enddo
115 
116  enddo
117 
118  !Apply rotational boundary condition
119  do rid = 1, n_rot
120  if( .not. rinfo%conds(rid)%active ) cycle
121  cdiff = 0.d0
122  cdiff0 = 0.d0
123  cddisp = 0.d0
124 
125  if( present(iter) ) then
126  if( iter > 1 ) then
127  rotation_factor = 0.d0 ! No additional rotation for subsequent iterations
128  else
129  rotation_factor = 1.0d0 ! Use the rotation vector as-is (already contains increment)
130  endif
131  else
132  rotation_factor = 1.0d0 ! Use the rotation vector as-is
133  endif
134 
135  if( rotation_factor > 0.d0 ) then
136  ig = rinfo%conds(rid)%center_ngrp_id
137  do idof = 1, ndof
138  ccoord(idof) = hecmw_ngrp_get_totalvalue(hecmesh, ig, ndof, idof, hecmesh%node)
139  cdisp(idof) = hecmw_ngrp_get_totalvalue(hecmesh, ig, ndof, idof, fstrsolid%unode)
140  cddisp(idof) = hecmw_ngrp_get_totalvalue(hecmesh, ig, ndof, idof, hecebc%val)
141  enddo
142  ccoord(1:ndof) = ccoord(1:ndof) + cdisp(1:ndof)
143  endif
144 
145  ig = rinfo%conds(rid)%torque_ngrp_id
146  is0 = hecmesh%node_group%grp_index(ig-1) + 1
147  ie0 = hecmesh%node_group%grp_index(ig )
148  do ik = is0, ie0
149  in = hecmesh%node_group%grp_item(ik)
150  if( rotation_factor > 0.d0 ) then
151  cdiff0(1:ndof) = hecmesh%node(ndof*(in-1)+1:ndof*in)+fstrsolid%unode(ndof*(in-1)+1:ndof*in)-ccoord(1:ndof)
152  cdiff(1:ndof) = cdiff0(1:ndof)
153  call rotate_3dvector_by_rodrigues_formula(rinfo%conds(rid)%vec(1:ndof),cdiff(1:ndof))
154  endif
155  do idof = 1, ndof
156  rhs = cdiff(idof)-cdiff0(idof)+cddisp(idof)
157  call hecmw_ebc_set(hecebc, in, idof, rhs)
158  if( fstr_is_contact_active() .and. fstrparam%solution_type == kststatic &
159  .and. fstrparam%contact_algo == kcaslagrange ) then
160  if(present(conmat)) then
161  call hecmw_mat_ass_bc_contactlag(conmat,heclagmat,in,idof,rhs)
162  else
163  call hecmw_mat_ass_bc_contactlag(hecmat,heclagmat,in,idof,rhs)
164  endif
165  endif
166  enddo
167  enddo
168  enddo
169  !C
170  !C-- end of implicit dynamic analysis
171  !C
172 
173  !C=============================C
174  !C-- explicit dynamic analysis
175  !C=============================C
176  else if( fstrdynamic%idx_eqa == 11 ) then
177  !C
178  ndof = hecmat%NDOF
179  do ig0 = 1, fstrsolid%BOUNDARY_ngrp_tot
180  ig = fstrsolid%BOUNDARY_ngrp_ID(ig0)
181  rhs = fstrsolid%BOUNDARY_ngrp_val(ig0)
182 
183  call fstr_get_amplitude_dyn(hecmesh, fstrsolid, fstrdynamic, ig0, t_curr, rhs, flag_u)
184 
185  ityp = fstrsolid%BOUNDARY_ngrp_type(ig0)
186 
187  is0 = hecmesh%node_group%grp_index(ig-1) + 1
188  ie0 = hecmesh%node_group%grp_index(ig )
189  idofs = ityp/10
190  idofe = ityp - idofs*10
191 
192  do ik = is0, ie0
193  in = hecmesh%node_group%grp_item(ik)
194 
195  do idof = idofs, idofe
196  hecmat%B (ndof*in-(ndof-idof)) = rhs
197  fstrdynamic%VEC1(ndof*in-(ndof-idof)) = 1.0d0
198  end do
199  enddo
200  enddo
201  !C
202  !C-- end of explicit dynamic analysis
203  !C
204  end if
205 
206  if( n_rot > 0 ) call fstr_rotinfo_finalize(rinfo)
207 
208  end subroutine dynamic_mat_ass_bc
209 
210 
211  !C***
213  !C***
214  subroutine dynamic_bc_init(hecMESH, hecMAT, fstrSOLID ,fstrDYNAMIC, t_curr)
215  use m_fstr
216  use m_table_dyn
217 
218  implicit none
219  type(hecmwst_matrix) :: hecmat
220  type(hecmwst_local_mesh) :: hecMESH
221  type(fstr_solid) :: fstrSOLID
222  type(fstr_dynamic) :: fstrDYNAMIC
223  real(kind=kreal) :: t_curr
224 
225  integer(kind=kint) :: NDOF, ig0, ig, ityp, iS0, iE0, ik, in, idofS, idofE, idof
226  integer(kind=kint) :: flag_u, grpid
227  real(kind=kreal) :: rhs, f_t
228 
229  flag_u = 1
230  ndof = hecmat%NDOF
231 
232  do ig0 = 1, fstrsolid%BOUNDARY_ngrp_tot
233  ig = fstrsolid%BOUNDARY_ngrp_ID(ig0)
234  rhs = fstrsolid%BOUNDARY_ngrp_val(ig0)
235  grpid = fstrsolid%BOUNDARY_ngrp_GRPID(ig0)
236  if( .not. fstr_isboundaryactive( fstrsolid, grpid, 1 ) ) cycle
237 
238  call fstr_get_amplitude_dyn(hecmesh, fstrsolid, fstrdynamic, ig0, t_curr, rhs, flag_u)
239 
240  ityp = fstrsolid%BOUNDARY_ngrp_type(ig0)
241 
242  is0 = hecmesh%node_group%grp_index(ig-1) + 1
243  ie0 = hecmesh%node_group%grp_index(ig )
244  idofs = ityp/10
245  idofe = ityp - idofs*10
246 
247  do ik = is0, ie0
248  in = hecmesh%node_group%grp_item(ik)
249 
250  do idof = idofs, idofe
251  fstrdynamic%DISP(ndof*in-(ndof-idof),1) = rhs
252  end do
253  enddo
254  enddo
255 
256  return
257  end subroutine dynamic_bc_init
258 
260  subroutine dynamic_explicit_ass_bc(hecMESH, hecMAT, fstrSOLID ,fstrDYNAMIC, t_curr, iter)
261  use m_fstr
262  use m_table_dyn
263  use mcontact
264  use m_utilities
265 
266  implicit none
267  type(hecmwst_matrix) :: hecmat
268  type(hecmwst_local_mesh) :: hecMESH
269  type(fstr_solid) :: fstrSOLID
270  type(fstr_dynamic) :: fstrDYNAMIC
271  real(kind=kreal) :: t_curr
272  integer, optional :: iter
273 
274  integer(kind=kint) :: ig0, ig, ityp, NDOF, iS0, iE0, ik, in, idofS, idofE, idof
275 
276  integer(kind=kint) :: flag_u
277  real(kind=kreal) :: rhs, f_t, f_t1
278 
279  !for rotation
280  integer(kind=kint) :: n_rot, rid, n_nodes
281  type(trotinfo) :: rinfo
282  real(kind=kreal) :: theta, normal(3), direc(3), ccoord(3), cdiff(3), cdiff0(3)
283  real(kind=kreal) :: cdisp(3), cddisp(3)
284  !
285  ndof = hecmat%NDOF
286  n_rot = fstrsolid%BOUNDARY_ngrp_rot
287  if( n_rot > 0 ) call fstr_rotinfo_init(n_rot, rinfo)
288 
289  flag_u = 1
290 
291  !C
292  ndof = hecmat%NDOF
293  do ig0 = 1, fstrsolid%BOUNDARY_ngrp_tot
294  ig = fstrsolid%BOUNDARY_ngrp_ID(ig0)
295  rhs = fstrsolid%BOUNDARY_ngrp_val(ig0)
296 
297  call fstr_get_amplitude_dyn(hecmesh, fstrsolid, fstrdynamic, ig0, t_curr, rhs, flag_u)
298 
299  ityp = fstrsolid%BOUNDARY_ngrp_type(ig0)
300 
301  is0 = hecmesh%node_group%grp_index(ig-1) + 1
302  ie0 = hecmesh%node_group%grp_index(ig )
303  idofs = ityp/10
304  idofe = ityp - idofs*10
305 
306  if( fstrsolid%BOUNDARY_ngrp_rotID(ig0) > 0 ) then ! setup rotation information
307  rid = fstrsolid%BOUNDARY_ngrp_rotID(ig0)
308  if( .not. rinfo%conds(rid)%active ) then
309  rinfo%conds(rid)%active = .true.
310  rinfo%conds(rid)%center_ngrp_id = fstrsolid%BOUNDARY_ngrp_centerID(ig0)
311  rinfo%conds(rid)%torque_ngrp_id = ig
312  endif
313  do idof=idofs,idofe
314  if( idof>ndof ) then
315  rinfo%conds(rid)%vec(idof-ndof) = rhs
316  else
317  rinfo%conds(rid)%vec(idof) = rhs
318  endif
319  enddo
320  cycle
321  endif
322 
323  do ik = is0, ie0
324  in = hecmesh%node_group%grp_item(ik)
325 
326  do idof = idofs, idofe
327  hecmat%B(ndof*in-(ndof-idof)) = rhs*fstrdynamic%VEC1(ndof*in-(ndof-idof))
328  ! fstrDYNAMIC%VEC1(NDOF*in-(NDOF-idof)) = 1.0d0
329  end do
330  enddo
331  enddo
332 
333  !Apply rotational boundary condition (prescribed absolute displacement)
334  ! The explicit scheme stores the absolute prescribed displacement in hecMAT%B
335  ! (B = u*VEC1, so that X = B/VEC1 = u). The rotation factor in rinfo%vec is the
336  ! total rotation at t_curr (val*f_t), hence the original offset r0 = x0 - c is
337  ! rotated and u = (R*r0 - r0) + c_disp.
338  do rid = 1, n_rot
339  if( .not. rinfo%conds(rid)%active ) cycle
340  cdiff = 0.d0
341  cdiff0 = 0.d0
342  cdisp = 0.d0
343 
344  ig = rinfo%conds(rid)%center_ngrp_id
345  do idof = 1, ndof
346  ccoord(idof) = hecmw_ngrp_get_totalvalue(hecmesh, ig, ndof, idof, hecmesh%node)
347  cdisp(idof) = hecmw_ngrp_get_totalvalue(hecmesh, ig, ndof, idof, fstrsolid%unode)
348  enddo
349 
350  ig = rinfo%conds(rid)%torque_ngrp_id
351  is0 = hecmesh%node_group%grp_index(ig-1) + 1
352  ie0 = hecmesh%node_group%grp_index(ig )
353  do ik = is0, ie0
354  in = hecmesh%node_group%grp_item(ik)
355  cdiff0(1:ndof) = hecmesh%node(ndof*(in-1)+1:ndof*in) - ccoord(1:ndof)
356  cdiff(1:ndof) = cdiff0(1:ndof)
357  call rotate_3dvector_by_rodrigues_formula(rinfo%conds(rid)%vec(1:ndof),cdiff(1:ndof))
358  do idof = 1, ndof
359  rhs = cdiff(idof) - cdiff0(idof) + cdisp(idof)
360  hecmat%B(ndof*in-(ndof-idof)) = rhs*fstrdynamic%VEC1(ndof*in-(ndof-idof))
361  enddo
362  enddo
363  enddo
364 
365  if( n_rot > 0 ) call fstr_rotinfo_finalize(rinfo)
366 
367  end subroutine dynamic_explicit_ass_bc
368 
369 end module m_dynamic_mat_ass_bc
Essential boundary conditions kept as per-DOF marks and values so that they can be imposed on the mat...
subroutine, public hecmw_ebc_set(hecEBC, inode, idof, val)
This module contains functions to set displacement boundary condition in dynamic analysis.
subroutine dynamic_mat_ass_bc(cstep, hecMESH, hecMAT, fstrSOLID, fstrDYNAMIC, fstrPARAM, hecLagMAT, hecEBC, t_curr, iter, conMAT)
This subroutine setup disp bundary condition.
subroutine dynamic_explicit_ass_bc(hecMESH, hecMAT, fstrSOLID, fstrDYNAMIC, t_curr, iter)
This subroutine setup disp boundary condition.
subroutine dynamic_bc_init(hecMESH, hecMAT, fstrSOLID, fstrDYNAMIC, t_curr)
This subroutine setup initial condition of displacement.
This module defines common data and basic structures for analysis.
Definition: m_fstr.F90:15
integer(kind=kint), parameter kcaslagrange
contact analysis algorithm
Definition: m_fstr.F90:62
integer(kind=kint), parameter kststatic
Definition: m_fstr.F90:38
logical function fstr_isboundaryactive(fstrSOLID, nbc, cstep)
Definition: m_fstr.F90:1092
Amplitude evaluation for loading conditions in dynamic analysis.
Definition: table_dyn.f90:6
subroutine fstr_get_amplitude_dyn(hecMESH, fstrSOLID, fstrDYNAMIC, ig0, t_curr, value, flag_u)
Evaluate the amplitude-scaled target value a(t) for dynamic analysis.
Definition: table_dyn.f90:28
This module provides aux functions.
Definition: utilities.f90:6
subroutine rotate_3dvector_by_rodrigues_formula(r, v)
Definition: utilities.f90:591
Top-level contact analysis module (System level)
logical function fstr_is_contact_active()
Whether contact stiffness and residual have to be assembled. Broader than is_contact_active(state): a...
Data for DYNAMIC ANSLYSIS (fstrDYNAMIC)
Definition: m_fstr.F90:544
FSTR INNER CONTROL PARAMETERS (fstrPARAM)
Definition: m_fstr.F90:161