FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_precond_rbm.f90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! Copyright (c) 2026 FrontISTR Commons
3 ! This software is released under the MIT License, see License.txt
4 !-------------------------------------------------------------------------------
23  use hecmw_util
24  use hecmw_etype
26  implicit none
27 
28  private
30 
31 contains
32 
33  subroutine hecmw_precond_rbm_from_mesh(hecMESH, ndof, rbm)
34  implicit none
35  type(hecmwst_local_mesh), intent(in) :: hecmesh
36  integer(kind=kint), intent(in) :: ndof
37  real(kind=kreal), intent(out) :: rbm(*)
38  integer(kind=kint), allocatable :: mark(:)
39  integer(kind=kint) :: nint, vl, nmode, node, base
40  integer(kind=kint) :: itype, ic_type, nn, is, ie, icel, iis, j, nod
41  real(kind=kreal) :: cx, cy, cz, x, y, z, csum(4)
42 
43  nint = hecmesh%nn_internal
44  vl = nint * ndof
45  select case (ndof)
46  case (1); nmode = 1
47  case (2); nmode = 3
48  case default; nmode = 6
49  end select
50 
51  ! mark 33struct shell rotation nodes (latter-half element nodes)
52  allocate(mark(hecmesh%n_node)); mark = 0
53  if (ndof == 3) then
54  do itype = 1, hecmesh%n_elem_type
55  ic_type = hecmesh%elem_type_item(itype)
56  if (hecmw_is_etype_33struct(ic_type)) then
57  nn = hecmw_get_max_node(ic_type)
58  is = hecmesh%elem_type_index(itype-1)+1
59  ie = hecmesh%elem_type_index(itype)
60  do icel = is, ie
61  iis = hecmesh%elem_node_index(icel-1)
62  do j = nn/2+1, nn
63  nod = hecmesh%elem_node_item(iis+j); mark(nod) = 1
64  end do
65  end do
66  end if
67  end do
68  end if
69 
70  ! global centroid, for well-conditioned rotation modes far from the origin
71  ! (sum of coordinates and node count reduced together in one allreduce)
72  csum = 0.0d0
73  do node = 1, nint
74  csum(1) = csum(1) + hecmesh%node(3*node-2)
75  csum(2) = csum(2) + hecmesh%node(3*node-1)
76  csum(3) = csum(3) + hecmesh%node(3*node)
77  end do
78  csum(4) = real(nint, kreal)
79  call hecmw_allreduce_r(hecmesh, csum, 4, hecmw_sum)
80  cx = 0.0d0; cy = 0.0d0; cz = 0.0d0
81  if (csum(4) > 0.0d0) then
82  cx = csum(1)/csum(4); cy = csum(2)/csum(4); cz = csum(3)/csum(4)
83  end if
84 
85  rbm(1:vl*nmode) = 0.0d0
86  if (ndof == 1) then
87  do node = 1, nint
88  rbm(node) = 1.0d0 ! constant
89  end do
90  else if (ndof == 2) then
91  do node = 1, nint
92  x = hecmesh%node(3*node-2) - cx; y = hecmesh%node(3*node-1) - cy
93  base = 2*(node-1)
94  rbm( base+1) = 1.0d0 ! trans-x
95  rbm( vl + base+2) = 1.0d0 ! trans-y
96  rbm( 2*vl + base+1) = -y ! rot-z
97  rbm( 2*vl + base+2) = x
98  end do
99  else ! ndof = 3 or 6
100  do node = 1, nint
101  base = ndof*(node-1)
102  if (ndof == 3 .and. mark(node) == 1) then
103  ! 33struct rotation node: rotational rigid-body modes only [0 | I3]
104  rbm( 3*vl + base+1) = 1.0d0
105  rbm( 4*vl + base+2) = 1.0d0
106  rbm( 5*vl + base+3) = 1.0d0
107  else
108  x = hecmesh%node(3*node-2) - cx
109  y = hecmesh%node(3*node-1) - cy
110  z = hecmesh%node(3*node) - cz
111  rbm( base+1) = 1.0d0 ! trans-x
112  rbm( vl + base+2) = 1.0d0 ! trans-y
113  rbm( 2*vl + base+3) = 1.0d0 ! trans-z
114  rbm( 3*vl + base+2) = -z ! rot-x
115  rbm( 3*vl + base+3) = y
116  rbm( 4*vl + base+1) = z ! rot-y
117  rbm( 4*vl + base+3) = -x
118  rbm( 5*vl + base+1) = -y ! rot-z
119  rbm( 5*vl + base+2) = x
120  if (ndof == 6) then
121  rbm( 3*vl + base+4) = 1.0d0 ! shell rotational DOF identity
122  rbm( 4*vl + base+5) = 1.0d0
123  rbm( 5*vl + base+6) = 1.0d0
124  end if
125  end if
126  end do
127  end if
128 
129  deallocate(mark)
130  end subroutine hecmw_precond_rbm_from_mesh
131 
132 end module hecmw_precond_rbm
I/O and Utility.
integer(kind=kint) function hecmw_get_max_node(etype)
logical function hecmw_is_etype_33struct(etype)
Rigid-body / near-kernel modes from mesh coordinates.
subroutine, public hecmw_precond_rbm_from_mesh(hecMESH, ndof, rbm)
I/O and Utility.
Definition: hecmw_util_f.F90:7
integer(kind=kint), parameter hecmw_sum
integer(kind=4), parameter kreal
subroutine hecmw_allreduce_r(hecMESH, val, n, ntag)