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