FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
fstr_Residual.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  use hecmw
10  implicit none
11 
12  public :: fstr_update_ndforce
13  public :: fstr_update_ndforce_spc
14  public :: fstr_update_reaction_spc
15  public :: fstr_get_residual
16  public :: fstr_get_norm_contact
19  public :: fstr_get_x_norm_contact
20  public :: fstr_get_potential
21 
22  private :: fstr_update_ndforce_mpc
23 
24 contains
25 
26  !C---------------------------------------------------------------------*
27  subroutine fstr_update_ndforce(cstep,hecMESH,hecMAT,fstrSOLID,conMAT)
28  !C---------------------------------------------------------------------*
34  use m_fstr
35  use muload
36  use m_fstr_spring
37  integer(kind=kint), intent(in) :: cstep
38  type(hecmwst_local_mesh), intent(in) :: hecmesh
39  type(hecmwst_matrix), intent(inout) :: hecmat
40  type(fstr_solid), intent(inout) :: fstrsolid
41  type(hecmwst_matrix), intent(inout), optional :: conmat
42  ! Local variables
43  integer(kind=kint) :: ndof, idof
44  real(kind=kreal) :: factor
45 
46  factor = fstrsolid%factor(2)
47 
48  ! Set residual load
49  do idof=1, hecmesh%n_node* hecmesh%n_dof
50  hecmat%B(idof)=fstrsolid%GL(idof)-fstrsolid%QFORCE(idof)
51  end do
52  ndof = hecmat%NDOF
53 
54  call fstr_update_ndforce_spring( cstep, hecmesh, fstrsolid, hecmat%B )
55 
56  ! Consider Uload
57  call uresidual( cstep, factor, hecmat%B )
58 
59  ! Consider EQUATION condition
60  call fstr_update_ndforce_mpc( hecmesh, hecmat%B )
61 
62  ! Consider SPC condition
63  call fstr_update_ndforce_spc( cstep, hecmesh, fstrsolid, hecmat%B )
64  if(present(conmat)) call fstr_update_ndforce_spc( cstep, hecmesh, fstrsolid, conmat%B )
65 
66  !
67  call hecmw_update_r(hecmesh,hecmat%B,hecmesh%n_node, ndof)
68  end subroutine fstr_update_ndforce
69 
70  subroutine fstr_update_ndforce_mpc( hecMESH, B )
71  use m_fstr
72  type(hecmwst_local_mesh), intent(in) :: hecmesh
73  real(kind=kreal), intent(inout) :: b(:)
74  ! Local variables
75  integer(kind=kint) ndof, ig0, is0, ie0, ik, in, idof
76  real(kind=kreal) :: rhs, lambda
77 
78  ndof = hecmesh%n_dof
79  outer: do ig0=1,hecmesh%mpc%n_mpc
80  is0= hecmesh%mpc%mpc_index(ig0-1)+1
81  ie0= hecmesh%mpc%mpc_index(ig0)
82  do ik= is0, ie0
83  if (hecmesh%mpc%mpc_dof(ik) > ndof) cycle outer
84  enddo
85  ! Suppose the lagrange multiplier= first dof of first node
86  in = hecmesh%mpc%mpc_item(is0)
87  idof = hecmesh%mpc%mpc_dof(is0)
88  rhs = hecmesh%mpc%mpc_val(is0)
89  lambda = b(ndof*(in-1)+idof)/rhs
90  ! update nodal residual
91  do ik= is0, ie0
92  in = hecmesh%mpc%mpc_item(ik)
93  idof = hecmesh%mpc%mpc_dof(ik)
94  rhs = hecmesh%mpc%mpc_val(ik)
95  b(ndof*(in-1)+idof) = b(ndof*(in-1)+idof) - rhs*lambda
96  enddo
97  enddo outer
98  end subroutine fstr_update_ndforce_mpc
99 
100  subroutine fstr_update_ndforce_spc( cstep, hecMESH, fstrSOLID, B )
101  use m_fstr
102  integer(kind=kint), intent(in) :: cstep
103  type(hecmwst_local_mesh), intent(in) :: hecmesh
104  type(fstr_solid), intent(in) :: fstrsolid
105  real(kind=kreal), intent(inout) :: b(:)
106  ! Local variables
107  integer(kind=kint) ndof, ig0, ig, ityp, is0, ie0, ik, in, idof1, idof2, idof
108  integer(kind=kint) :: grpid
109 
110  ndof = hecmesh%n_dof
111 
112  ! Clear RHS at constrained DOFs (SPC)
113  do ig0= 1, fstrsolid%BOUNDARY_ngrp_tot
114  grpid = fstrsolid%BOUNDARY_ngrp_GRPID(ig0)
115  if( .not. fstr_isboundaryactive( fstrsolid, grpid, cstep ) ) cycle
116  ig= fstrsolid%BOUNDARY_ngrp_ID(ig0)
117  ityp= fstrsolid%BOUNDARY_ngrp_type(ig0)
118  is0= hecmesh%node_group%grp_index(ig-1) + 1
119  ie0= hecmesh%node_group%grp_index(ig )
120  do ik= is0, ie0
121  in = hecmesh%node_group%grp_item(ik)
122  idof1 = ityp/10
123  idof2 = ityp - idof1*10
124  if( fstrsolid%BOUNDARY_ngrp_rotID(ig0) > 0 ) then
125  idof1 = 1
126  idof2 = ndof
127  end if
128  do idof=idof1,idof2
129  b( ndof*(in-1) + idof ) = 0.d0
130  enddo
131  enddo
132  enddo
133  end subroutine fstr_update_ndforce_spc
134 
140  subroutine fstr_update_reaction_spc( cstep, hecMESH, fstrSOLID )
141  use m_fstr
142  integer(kind=kint), intent(in) :: cstep
143  type(hecmwst_local_mesh), intent(in) :: hecmesh
144  type(fstr_solid), intent(in) :: fstrsolid
145  ! Local variables
146  integer(kind=kint) :: ndof, ig0, ig, ityp, is0, ie0, ik, in, idof1, idof2, idof
147  integer(kind=kint) :: grpid
148 
149  ndof = hecmesh%n_dof
150  fstrsolid%REACTION = 0.d0
151 
152  ! displacement boundary
153  do ig0= 1, fstrsolid%BOUNDARY_ngrp_tot
154  grpid = fstrsolid%BOUNDARY_ngrp_GRPID(ig0)
155  if( .not. fstr_isboundaryactive( fstrsolid, grpid, cstep ) ) cycle
156  ig= fstrsolid%BOUNDARY_ngrp_ID(ig0)
157  ityp= fstrsolid%BOUNDARY_ngrp_type(ig0)
158  is0= hecmesh%node_group%grp_index(ig-1) + 1
159  ie0= hecmesh%node_group%grp_index(ig )
160  do ik= is0, ie0
161  in = hecmesh%node_group%grp_item(ik)
162  idof1 = ityp/10
163  idof2 = ityp - idof1*10
164  if( fstrsolid%BOUNDARY_ngrp_rotID(ig0) > 0 ) then
165  idof1 = 1
166  idof2 = ndof
167  end if
168  do idof=idof1,idof2
169  fstrsolid%REACTION(ndof*(in-1)+idof) = fstrsolid%QFORCE(ndof*(in-1)+idof)
170  !count embed force as reaction force
171  if( associated(fstrsolid%EMBED_NFORCE) ) fstrsolid%REACTION(ndof*(in-1)+idof) = &
172  & fstrsolid%QFORCE(ndof*(in-1)+idof) - fstrsolid%EMBED_NFORCE(ndof*(in-1)+idof)
173  enddo
174  enddo
175  enddo
176 
177  ! velocity boundary (dynamic only; following type constrains the DOF)
178  if( fstrsolid%VELOCITY_type /= kbcinitial ) then
179  do ig0= 1, fstrsolid%VELOCITY_ngrp_tot
180  grpid = fstrsolid%VELOCITY_ngrp_GRPID(ig0)
181  if( .not. fstr_isboundaryactive( fstrsolid, grpid, cstep ) ) cycle
182  ig= fstrsolid%VELOCITY_ngrp_ID(ig0)
183  ityp= fstrsolid%VELOCITY_ngrp_type(ig0)
184  is0= hecmesh%node_group%grp_index(ig-1) + 1
185  ie0= hecmesh%node_group%grp_index(ig )
186  idof1 = ityp/10
187  idof2 = ityp - idof1*10
188  do ik= is0, ie0
189  in = hecmesh%node_group%grp_item(ik)
190  do idof=idof1,idof2
191  fstrsolid%REACTION(ndof*(in-1)+idof) = fstrsolid%QFORCE(ndof*(in-1)+idof)
192  enddo
193  enddo
194  enddo
195  endif
196 
197  ! acceleration boundary (dynamic only; following type constrains the DOF)
198  if( fstrsolid%ACCELERATION_type /= kbcinitial ) then
199  do ig0= 1, fstrsolid%ACCELERATION_ngrp_tot
200  grpid = fstrsolid%ACCELERATION_ngrp_GRPID(ig0)
201  if( .not. fstr_isboundaryactive( fstrsolid, grpid, cstep ) ) cycle
202  ig= fstrsolid%ACCELERATION_ngrp_ID(ig0)
203  ityp= fstrsolid%ACCELERATION_ngrp_type(ig0)
204  is0= hecmesh%node_group%grp_index(ig-1) + 1
205  ie0= hecmesh%node_group%grp_index(ig )
206  idof1 = ityp/10
207  idof2 = ityp - idof1*10
208  do ik= is0, ie0
209  in = hecmesh%node_group%grp_item(ik)
210  do idof=idof1,idof2
211  fstrsolid%REACTION(ndof*(in-1)+idof) = fstrsolid%QFORCE(ndof*(in-1)+idof)
212  enddo
213  enddo
214  enddo
215  endif
216  end subroutine fstr_update_reaction_spc
217 
218 
220  subroutine fstr_calc_residual_vector(hecMESH, hecMAT, fstrSOLID, ctime, tincr, iter, cstep, dtime, fstrPARAM)
221  use m_fstr_update
222  use m_fstr_ass_load
223  implicit none
224  integer, intent(in) :: cstep
225  type (hecmwST_local_mesh) :: hecMESH
226  type (hecmwST_matrix) :: hecMAT
227  type (fstr_solid) :: fstrSOLID
228  real(kind=kreal), intent(in) :: ctime
229  real(kind=kreal), intent(in) :: dtime
230  type (fstr_param) :: fstrPARAM
231  real(kind=kreal), intent(in) :: tincr
232  integer(kind=kint) :: iter
233 
234  ! ----- update the strain, stress, and internal force
235  call fstr_updatenewton(hecmesh, hecmat, fstrsolid, ctime, tincr, iter)
236 
237  ! ----- Set residual
238  if( fstrsolid%DLOAD_follow /= 0 .or. fstrsolid%CLOAD_ngrp_rot /= 0 ) &
239  & call fstr_ass_load(cstep, ctime+dtime, hecmesh, hecmat, fstrsolid, fstrparam )
240 
241 
242  if( fstrsolid%elemact%ELEMACT_egrp_tot > 0 ) then
243  call fstr_update_elemact_solid_by_value( hecmesh, fstrsolid, cstep, ctime )
244  endif
245 
246  call fstr_update_ndforce(cstep, hecmesh, hecmat, fstrsolid)
247 
248  end subroutine fstr_calc_residual_vector
249 
251  subroutine fstr_calc_residual_vector_with_x(hecMESH, hecMAT, fstrSOLID, ctime, tincr, iter, cstep, dtime, fstrPARAM)
254  implicit none
255  integer, intent(in) :: cstep
256  type (hecmwST_local_mesh) :: hecMESH
257  type (hecmwST_matrix) :: hecMAT
258  type (fstr_solid) :: fstrSOLID
259  real(kind=kreal), intent(in) :: ctime
260  real(kind=kreal), intent(in) :: dtime
261  type (fstr_param) :: fstrPARAM
262  real(kind=kreal), intent(in) :: tincr
263  integer(kind=kint) :: iter
264 
265  integer :: i
266  real(kind=kreal) :: dunode_bak(hecmat%ndof*hecmesh%n_node)
267  real(kind=kreal), allocatable :: shell_dtriad_bak(:), shell_ddrill_bak(:)
268 
269  do i=1, hecmat%ndof*hecmesh%n_node
270  dunode_bak(i) = fstrsolid%dunode(i)
271  enddo
272  if( associated(fstrsolid%shell_dtriad) ) then
273  allocate(shell_dtriad_bak(size(fstrsolid%shell_dtriad)))
274  shell_dtriad_bak(:) = fstrsolid%shell_dtriad(:)
275  endif
276  if( associated(fstrsolid%shell_ddrill) ) then
277  allocate(shell_ddrill_bak(size(fstrsolid%shell_ddrill)))
278  shell_ddrill_bak(:) = fstrsolid%shell_ddrill(:)
279  endif
280  call fstr_apply_solution_increment( hecmesh, fstrsolid, hecmat%ndof, hecmat%X )
281  call fstr_calc_residual_vector(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam)
282  do i=1, hecmat%ndof*hecmesh%n_node
283  fstrsolid%dunode(i) = dunode_bak(i)
284  enddo
285  if( allocated(shell_dtriad_bak) ) then
286  fstrsolid%shell_dtriad(:) = shell_dtriad_bak(:)
287  deallocate(shell_dtriad_bak)
288  endif
289  if( allocated(shell_ddrill_bak) ) then
290  fstrsolid%shell_ddrill(:) = shell_ddrill_bak(:)
291  deallocate(shell_ddrill_bak)
292  endif
293  end subroutine fstr_calc_residual_vector_with_x
294 
296  real(kind=kreal) function fstr_get_residual( force, hecMESH )
297  use m_fstr
298  real(kind=kreal), intent(in) :: force(:)
299  type(hecmwst_local_mesh), intent(in) :: hecmesh
300  integer :: ndof
301  ndof = hecmesh%n_dof
302  call hecmw_innerproduct_r(hecmesh,ndof,force,force,fstr_get_residual)
303  end function
304 
306  real(kind=kreal) function fstr_get_energy( force, displacement, hecMESH )
307  use m_fstr
308  real(kind=kreal), intent(in) :: force(:), displacement(:)
309  type(hecmwst_local_mesh), intent(in) :: hecmesh
310  integer :: ndof
311  ndof = hecmesh%n_dof
312  call hecmw_innerproduct_r(hecmesh, ndof, force, displacement, fstr_get_energy)
313  end function
314 
316  real(kind=kreal) function fstr_get_norm_contact(flag,hecMESH,hecMAT,fstrSOLID,hecLagMAT)
317  use m_fstr
318  type(hecmwst_local_mesh), intent(in) :: hecmesh
319  type(hecmwst_matrix), intent(in) :: hecmat
320  type(fstr_solid), intent(in) :: fstrsolid
321  type(hecmwst_matrix_lagrange), intent(in) :: heclagmat
322  character(len=13) :: flag
323  real(kind=kreal) :: tmp1, tmp2, bi
324  integer :: i, i0, ndof
325  if( flag=='residualForce' )then
326  ndof = hecmesh%n_dof
327  call hecmw_innerproduct_r(hecmesh,ndof,hecmat%B,hecmat%B,tmp1)
328  tmp2 = 0.0d0
329  i0 = hecmesh%n_node*ndof
330  do i=1,heclagmat%num_lagrange
331  bi = hecmat%B(i0+i)
332  tmp2 = tmp2 + bi*bi
333  enddo
334  call hecmw_allreduce_r1(hecmesh,tmp2,hecmw_sum)
335  fstr_get_norm_contact = tmp1 + tmp2
336  elseif( flag==' force' )then
337  call hecmw_innerproduct_r(hecmesh,ndof,fstrsolid%QFORCE,fstrsolid%QFORCE,fstr_get_norm_contact)
338  endif
339  end function
340 
346  subroutine fstr_assemble_residual_contact(hecMAT, hecLagMAT, conMAT, hecMESH, resid_vec, nresid)
347  use m_fstr
348  implicit none
349  type(hecmwst_matrix), intent(in) :: hecmat
350  type(hecmwst_matrix_lagrange), intent(in) :: heclagmat
351  type(hecmwst_matrix), intent(in) :: conmat
352  type(hecmwst_local_mesh), intent(in) :: hecmesh
353  real(kind=kreal), intent(out) :: resid_vec(:)
354  integer(kind=kint), intent(out) :: nresid
355 
356  integer(kind=kint) :: i, ndof, nndof, npndof, num_lagrange
357 
358  ndof = conmat%ndof
359  nndof = conmat%N * ndof
360  npndof = conmat%NP * ndof
361  num_lagrange = heclagmat%num_lagrange
362  nresid = nndof + num_lagrange
363 
364  ! Copy conMAT%B and assemble across MPI
365  do i = 1, npndof
366  resid_vec(i) = conmat%B(i)
367  enddo
368  call hecmw_assemble_r(hecmesh, resid_vec, conmat%NP, conmat%NDOF)
369 
370  ! Add hecMAT%B (node DOFs only)
371  do i = 1, nndof
372  resid_vec(i) = resid_vec(i) + hecmat%B(i)
373  enddo
374 
375  ! Copy Lagrange multiplier residual
376  do i = 1, num_lagrange
377  resid_vec(nndof + i) = conmat%B(npndof + i)
378  enddo
379 
380  end subroutine fstr_assemble_residual_contact
381 
382  !
383  function fstr_get_norm_para_contact(hecMAT,hecLagMAT,conMAT,hecMESH) result(rhsB)
384  use m_fstr
385  implicit none
386  type(hecmwst_matrix), intent(in) :: hecmat
387  type(hecmwst_matrix_lagrange), intent(in) :: heclagmat
388  type(hecmwst_matrix), intent(in) :: conmat
389  type(hecmwst_local_mesh), intent(in) :: hecmesh
390  !
391  real(kind=kreal) :: rhsb
392  integer(kind=kint) :: i,ndof,nndof,npndof,num_lagrange
393  real(kind=kreal), allocatable :: rhs_con(:)
394  real(kind=kreal), pointer :: rhs_lag(:)
395 
396  ndof = conmat%ndof
397  nndof = conmat%N * ndof
398  npndof = conmat%NP * ndof
399  num_lagrange = heclagmat%num_lagrange
400 
401  allocate(rhs_con(npndof))
402  do i=1,npndof
403  rhs_con(i) = conmat%B(i)
404  enddo
405  call hecmw_assemble_r(hecmesh, rhs_con, conmat%NP, conmat%NDOF)
406 
407  do i=1,nndof
408  rhs_con(i) = rhs_con(i) + hecmat%B(i)
409  enddo
410 
411  rhs_lag => conmat%B(npndof+1:npndof+num_lagrange)
412 
413  rhsb = dot_product(rhs_con(1:nndof), rhs_con(1:nndof)) + dot_product(rhs_lag(:), rhs_lag(:))
414  call hecmw_allreduce_r1(hecmesh, rhsb, hecmw_sum)
415  deallocate(rhs_con)
416 
417  end function fstr_get_norm_para_contact
418 
419  function fstr_get_x_norm_contact(hecMAT,hecLagMAT,hecMESH) result(rhsX)
420  use m_fstr
421  implicit none
422  type(hecmwst_matrix), intent(in) :: hecmat
423  type(hecmwst_matrix_lagrange), intent(in) :: heclagmat
424  type(hecmwst_local_mesh), intent(in) :: hecmesh
425  real(kind=kreal) :: rhsx
426  integer(kind=kint) :: nndof, npndof, i
427 
428  nndof = hecmat%N * hecmat%NDOF
429  npndof = hecmat%NP * hecmat%NDOF
430  rhsx = 0.d0
431  do i=1,nndof
432  rhsx = rhsx + hecmat%X(i) ** 2
433  end do
434  do i=1,heclagmat%num_lagrange
435  rhsx = rhsx + hecmat%X(npndof+i) ** 2
436  end do
437  call hecmw_allreduce_r1(hecmesh, rhsx, hecmw_sum)
438 
439  end function fstr_get_x_norm_contact
440 
441  !C---------------------------------------------------------------------*
442  function fstr_get_potential(cstep,hecMESH,hecMAT,fstrSOLID,ptype) result(potential)
443  use m_fstr
444  use muload
445  use m_fstr_spring
446  integer(kind=kint), intent(in) :: cstep
447  type(hecmwst_local_mesh), intent(in) :: hecmesh
448  type(hecmwst_matrix), intent(inout) :: hecmat
449  type(fstr_solid), intent(inout) :: fstrsolid
450  integer(kind=kint), intent(in) :: ptype
451  real(kind=kreal) :: potential
452  ! Local variables
453  integer(kind=kint) :: ndof, i, icel, icel0, ig
454  real(kind=kreal), allocatable :: totdisp(:), totload(:)
455  real(kind=kreal) :: factor
456  real(kind=kreal) :: extenal_work, internal_work
457 
458  ndof = hecmat%NDOF
459  factor = fstrsolid%factor(2)
460  potential = 0.d0
461 
462  allocate(totload(ndof*hecmesh%n_node))
463 
464  ! Set external load
465  do i=1,ndof*hecmesh%n_node
466  totload(i) = 0.5d0*(fstrsolid%GL(i)+fstrsolid%GL0(i))
467  end do
468  ! Consiter Spring
469  call fstr_update_ndforce_spring( cstep, hecmesh, fstrsolid, totload )
470  ! Consider Uload
471  call uresidual( cstep, factor, totload )
472  ! Consider EQUATION condition
473  call fstr_update_ndforce_mpc( hecmesh, totload )
474 
475  if( ptype == 1 ) then
476  ! calc internal work
477  internal_work = 0.d0
478  do icel0=1,hecmesh%ne_internal
479  icel=hecmesh%elem_internal_list(icel0)
480  do ig=1,size(fstrsolid%elements(icel)%gausses)
481  internal_work = internal_work + fstrsolid%elements(icel)%gausses(ig)%strain_energy
482  enddo
483  enddo
484  call hecmw_allreduce_r1(hecmesh, internal_work, hecmw_sum)
485  ! calc external work
486  call hecmw_innerproduct_r(hecmesh,ndof,totload,fstrsolid%dunode,extenal_work)
487  potential = internal_work - extenal_work
488  else if( ptype == 2 ) then ! multiply internal force with displacement
489  ! calc internal work
490  call hecmw_innerproduct_r(hecmesh,ndof,0.5d0*(fstrsolid%QFORCE+fstrsolid%QFORCE_bak),fstrsolid%dunode,internal_work)
491  ! calc external work
492  call hecmw_innerproduct_r(hecmesh,ndof,totload,fstrsolid%dunode,extenal_work)
493  potential = internal_work - extenal_work
494  else if( ptype == 3 ) then ! norm of residual
495  ! Consider internal force
496  totload(:) = fstrsolid%QFORCE(:) - totload(:)
497  ! Consider SPC condition
498  call fstr_update_ndforce_spc( cstep, hecmesh, fstrsolid, totload )
499  ! calc norm of residual
500  call hecmw_innerproduct_r(hecmesh,ndof,totload,totload,potential)
501  potential = dsqrt(potential)
502  else
503  stop "ptype error in fstr_get_potential"
504  endif
505  !write(IMSG,*) "internal_work,extenal_work",internal_work,extenal_work
506  end function fstr_get_potential
507 
508  function fstr_get_potential_with_x(cstep,hecMESH,hecMAT,fstrSOLID,ptype) result(potential)
509  use m_fstr
510  use muload
511  use m_fstr_spring
513  implicit none
514  integer(kind=kint), intent(in) :: cstep
515  type(hecmwst_local_mesh), intent(in) :: hecmesh
516  type(hecmwst_matrix), intent(inout) :: hecmat
517  type(fstr_solid), intent(inout) :: fstrsolid
518  integer(kind=kint), intent(in) :: ptype
519  real(kind=kreal) :: potential
520 
521  integer :: i
522  real(kind=kreal) :: dunode_bak(hecmat%ndof*hecmesh%n_node)
523  real(kind=kreal), allocatable :: shell_dtriad_bak(:), shell_ddrill_bak(:)
524 
525  do i=1, hecmat%ndof*hecmesh%n_node
526  dunode_bak(i) = fstrsolid%dunode(i)
527  enddo
528  if( associated(fstrsolid%shell_dtriad) ) then
529  allocate(shell_dtriad_bak(size(fstrsolid%shell_dtriad)))
530  shell_dtriad_bak(:) = fstrsolid%shell_dtriad(:)
531  endif
532  if( associated(fstrsolid%shell_ddrill) ) then
533  allocate(shell_ddrill_bak(size(fstrsolid%shell_ddrill)))
534  shell_ddrill_bak(:) = fstrsolid%shell_ddrill(:)
535  endif
536  call fstr_apply_solution_increment( hecmesh, fstrsolid, hecmat%ndof, hecmat%X )
537  potential = fstr_get_potential(cstep,hecmesh,hecmat,fstrsolid,ptype)
538  do i=1, hecmat%ndof*hecmesh%n_node
539  fstrsolid%dunode(i) = dunode_bak(i)
540  enddo
541  if( allocated(shell_dtriad_bak) ) then
542  fstrsolid%shell_dtriad(:) = shell_dtriad_bak(:)
543  deallocate(shell_dtriad_bak)
544  endif
545  if( allocated(shell_ddrill_bak) ) then
546  fstrsolid%shell_ddrill(:) = shell_ddrill_bak(:)
547  deallocate(shell_ddrill_bak)
548  endif
549  end function fstr_get_potential_with_x
550 
551  subroutine plot_potential_graph( cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, &
552  restrt_step_num, sub_step, ctime, dtime, iter, tincr )
553  use m_fstr
555  integer, intent(in) :: cstep
556  type (hecmwST_local_mesh) :: hecMESH
557  type (hecmwST_matrix) :: hecMAT
558  type (fstr_solid) :: fstrSOLID
559  integer, intent(in) :: sub_step
560  real(kind=kreal), intent(in) :: ctime
561  real(kind=kreal), intent(in) :: dtime
562  type (fstr_param) :: fstrPARAM
563  type (hecmwST_matrix_lagrange) :: hecLagMAT
564  integer(kind=kint) :: restrt_step_num
565 
566  integer(kind=kint) :: iter, i, j
567  integer(kind=kint), parameter :: ntot = 30
568  real(kind=kreal) :: tincr, alpha, dulen
569  real(kind=kreal) :: pot(3)
570  real(kind=kreal), allocatable :: dunode_bak(:)
571  real(kind=kreal), allocatable :: shell_dtriad_bak(:), shell_ddrill_bak(:)
572 
573  dulen = dsqrt(dot_product(fstrsolid%dunode(:),fstrsolid%dunode(:)))
574  write(imsg,*) "dulen",dulen
575 
576  allocate(dunode_bak(size(fstrsolid%dunode)))
577  do i=1, hecmat%ndof*hecmesh%n_node
578  dunode_bak(i) = fstrsolid%dunode(i)
579  enddo
580  if( associated(fstrsolid%shell_dtriad) ) then
581  allocate(shell_dtriad_bak(size(fstrsolid%shell_dtriad)))
582  shell_dtriad_bak(:) = fstrsolid%shell_dtriad(:)
583  endif
584  if( associated(fstrsolid%shell_ddrill) ) then
585  allocate(shell_ddrill_bak(size(fstrsolid%shell_ddrill)))
586  shell_ddrill_bak(:) = fstrsolid%shell_ddrill(:)
587  endif
588 
589  do i=-ntot,ntot
590  alpha = 5.d-3*dble(i)/dble(ntot)
591  hecmat%X(:) = alpha*fstrsolid%dunode(:)
592  fstrsolid%dunode(:) = dunode_bak(:)
593  if( allocated(shell_dtriad_bak) ) fstrsolid%shell_dtriad(:) = shell_dtriad_bak(:)
594  if( allocated(shell_ddrill_bak) ) fstrsolid%shell_ddrill(:) = shell_ddrill_bak(:)
595  call fstr_apply_solution_increment( hecmesh, fstrsolid, hecmat%ndof, hecmat%X )
596  call fstr_calc_residual_vector(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam)
597  pot(1) = fstr_get_potential(cstep,hecmesh,hecmat,fstrsolid,1)
598  pot(2) = fstr_get_potential(cstep,hecmesh,hecmat,fstrsolid,2)
599  pot(3) = fstr_get_potential(cstep,hecmesh,hecmat,fstrsolid,3)
600  write(imsg,'(I4,5(",",1pE16.9))') i,alpha,alpha*dulen,pot(1:3)
601  enddo
602 
603  do i=1, size(fstrsolid%dunode)
604  fstrsolid%dunode(i) = dunode_bak(i)
605  enddo
606  if( allocated(shell_dtriad_bak) ) then
607  fstrsolid%shell_dtriad(:) = shell_dtriad_bak(:)
608  deallocate(shell_dtriad_bak)
609  endif
610  if( allocated(shell_ddrill_bak) ) then
611  fstrsolid%shell_ddrill(:) = shell_ddrill_bak(:)
612  deallocate(shell_ddrill_bak)
613  endif
614  hecmat%X(:) = 0.d0
615  call fstr_calc_residual_vector_with_x(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam)
616  end subroutine
617 
618 end module m_fstr_residual
Definition: hecmw.f90:6
This module provides functions to take into account external load.
subroutine fstr_ass_load(cstep, ctime, hecMESH, hecMAT, fstrSOLID, fstrPARAM)
This subroutine assmble following external force into fstrSOLIDGL and hecMATB afterwards.
This module provide a function to elemact elements.
subroutine fstr_update_elemact_solid_by_value(hecMESH, fstrSOLID, cstep, ctime)
Finite-rotation nodal kinematics for NLGEOM.
subroutine, public fstr_apply_solution_increment(hecMESH, fstrSOLID, ndof, x)
Apply the linear-solver solution increment x to the step displacement dunode.
This module provides function to calculate residual of nodal force.
subroutine, public fstr_update_ndforce_spc(cstep, hecMESH, fstrSOLID, B)
subroutine, public fstr_update_ndforce(cstep, hecMESH, hecMAT, fstrSOLID, conMAT)
subroutine plot_potential_graph(cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, restrt_step_num, sub_step, ctime, dtime, iter, tincr)
real(kind=kreal) function, public fstr_get_norm_para_contact(hecMAT, hecLagMAT, conMAT, hecMESH)
real(kind=kreal) function, public fstr_get_residual(force, hecMESH)
Calculate magnitude of a real vector.
real(kind=kreal) function, public fstr_get_potential(cstep, hecMESH, hecMAT, fstrSOLID, ptype)
subroutine fstr_calc_residual_vector(hecMESH, hecMAT, fstrSOLID, ctime, tincr, iter, cstep, dtime, fstrPARAM)
\breaf This subroutine calculate residual vector
subroutine fstr_calc_residual_vector_with_x(hecMESH, hecMAT, fstrSOLID, ctime, tincr, iter, cstep, dtime, fstrPARAM)
\breaf This subroutine calculate residual vector
real(kind=kreal) function fstr_get_potential_with_x(cstep, hecMESH, hecMAT, fstrSOLID, ptype)
real(kind=kreal) function, public fstr_get_norm_contact(flag, hecMESH, hecMAT, fstrSOLID, hecLagMAT)
Calculate square norm.
real(kind=kreal) function fstr_get_energy(force, displacement, hecMESH)
Calculate magnitude of a real vector.
subroutine, public fstr_assemble_residual_contact(hecMAT, hecLagMAT, conMAT, hecMESH, resid_vec, nresid)
Assemble contact residual vector (hecMATB + conMATB + Lagrange) into a single vector.
real(kind=kreal) function, public fstr_get_x_norm_contact(hecMAT, hecLagMAT, hecMESH)
subroutine, public fstr_update_reaction_spc(cstep, hecMESH, fstrSOLID)
Set fstrSOLIDREACTION at constrained DOFs using current fstrSOLIDQFORCE. Constrained DOFs are enumera...
This module provides functions to deal with spring force.
Definition: fstr_Spring.f90:7
subroutine fstr_update_ndforce_spring(cstep, hecMESH, fstrSOLID, B)
Definition: fstr_Spring.f90:46
This module provides function to calculate to do updates.
Definition: fstr_Update.f90:6
subroutine fstr_updatenewton(hecMESH, hecMAT, fstrSOLID, time, tincr, iter, strainEnergy)
Update displacement, stress, strain and internal forces.
Definition: fstr_Update.f90:26
This module defines common data and basic structures for analysis.
Definition: m_fstr.F90:15
integer(kind=kint), parameter imsg
Definition: m_fstr.F90:112
integer(kind=kint), parameter kbcinitial
Definition: m_fstr.F90:68
logical function fstr_isboundaryactive(fstrSOLID, nbc, cstep)
Definition: m_fstr.F90:1053
This subroutine read in used-defined loading tangent.
Definition: uload.f90:7
subroutine uresidual(cstep, factor, residual)
This subroutine take consider of user-defined external loading.
Definition: uload.f90:39